在大多数脚本语言(例如Ruby,Python等)中,包管理器(例如gem,pip等)可以将脚本作为可执行文件安装,并将它们链接到PATH变量中引用的目录(例如/ usr / local /箱)。这将这些可执行脚本转换为shell命令,用户可以以独立方式在编程接口之外运行。
我想知道R中是否也存在这种可能性。鉴于R使用标准的Makefile,我想必须有办法这样做,尽管是非标准的。我已经知道我们可以在R脚本using the docopt
package中读取命令行参数。但有没有办法在安装包时将脚本安装为可执行文件?
在这个主题上取得领导会很棒,但CRAN的一个工作示例也足够了。
答案 0 :(得分:2)
简短(也很伤心)回答:你做不到。但请继续阅读。
推理:R只会将包内容写入自己的.libPaths()
目录(或第一个,如果有几个),或者是用户指定的目录。
所以说,/usr/local/bin/
根本无法触及。这是一种可辩护的策略。
这也很令人伤心 - 为了这个目的,我写了littler(也是CRAN page):可执行的R脚本。我们有数十个从cron
个工作中调用的工作人员。那么我们该怎么办?从包含脚本的程序包的scripts/
子目录到/usr/local/bin
的一次性软链接。在软件包升级时,链接将作为软链接保留。
这就是我为例如做的所有examples shipping with littler以及来自其他软件包的更多信息。他们中的许多人也使用docopt。
答案 1 :(得分:0)
我有一个相似的目标,这是我确定的解决方案。我向我的R包中添加了一个函数,该函数可以通过(详细地)创建从~/.local/bin
到我的包exec
文件夹中每个脚本的符号链接。
其他明智的默认位置可能是~/.local/lib/R/bin
或~/bin
,但我最喜欢~/.local/bin
。
因此,在安装软件包后,我指导用户运行
Rscript -e 'mypackage::install_executable_scripts()'
#' @export
install_executable_scripts <- function(into = "~/.local/bin", overwrite = FALSE) {
scripts <- dir(system.file("exec", package = "TKutils"),
full.names = TRUE)
if (!dir.exists(into)) dir.create(into)
into <- normalizePath(into)
dests <- file.path(normalizePath(into), basename(scripts))
if (any(already_exist <- file.exists(dests))) {
if (overwrite) {
to_del <- dests[already_exist]
cli::cat_bullet("Deleting existing file: ", to_del,
bullet_col = "red")
unlink(to_del)
} else {
cli::cat_bullet(sprintf(
"Skipping script '%s' because a file by that name already exists at the destination",
basename(scripts[already_exist])))
scripts <- scripts[!already_exist]
dests <- dests[!already_exist]
}
}
if (length(scripts)) {
file.symlink(scripts, dests)
cli::cat_line("Created symlinks:")
cli::cat_bullet(dests, " ->\n ", scripts, bullet_col = "green")
} else
cli::cat_line("Nothing installed")
PATHS <- normalizePath(strsplit(Sys.getenv("PATH"), ":", fixed = TRUE)[[1]],
mustWork = FALSE)
if(!into %in% PATHS)
warning(sprintf("destination '%s' is not on the PATH", into))
}