我有一个名为foo的脚本。R包含另一个脚本other。R,在同一个目录下:
#!/usr/bin/env Rscript
message("Hello")
source("other.R")
但我想让R找到另一个。R,不管当前工作目录是什么。
换句话说,就是foo。R需要知道自己的路径。我该怎么做呢?
我有一个名为foo的脚本。R包含另一个脚本other。R,在同一个目录下:
#!/usr/bin/env Rscript
message("Hello")
source("other.R")
但我想让R找到另一个。R,不管当前工作目录是什么。
换句话说,就是foo。R需要知道自己的路径。我该怎么做呢?
当前回答
当从R控制台“来源”时,我无法得到Suppressingfire的解决方案。 当使用Rscript时,我无法得到hadley的解决方案。
两全其美?
thisFile <- function() {
cmdArgs <- commandArgs(trailingOnly = FALSE)
needle <- "--file="
match <- grep(needle, cmdArgs)
if (length(match) > 0) {
# Rscript
return(normalizePath(sub(needle, "", cmdArgs[match])))
} else {
# 'source'd via R console
return(normalizePath(sys.frames()[[1]]$ofile))
}
}
其他回答
当从R控制台“来源”时,我无法得到Suppressingfire的解决方案。 当使用Rscript时,我无法得到hadley的解决方案。
两全其美?
thisFile <- function() {
cmdArgs <- commandArgs(trailingOnly = FALSE)
needle <- "--file="
match <- grep(needle, cmdArgs)
if (length(match) > 0) {
# Rscript
return(normalizePath(sub(needle, "", cmdArgs[match])))
} else {
# 'source'd via R console
return(normalizePath(sys.frames()[[1]]$ofile))
}
}
通过查看调用堆栈,我们可以获得正在执行的每个脚本的文件路径,其中最有用的两个可能是当前正在执行的脚本,或者是要获取的第一个脚本(条目)。
script.dir.executing = (function() return( if(length(sys.parents())==1) getwd() else dirname( Filter(is.character,lapply(rev(sys.frames()),function(x) x$ofile))[[1]] ) ))()
script.dir.entry = (function() return( if(length(sys.parents())==1) getwd() else dirname(sys.frame(1)$ofile) ))()
我对上面的实现有问题,因为我的脚本是从符号链接目录操作的,或者至少这就是为什么我认为上面的解决方案不适合我。按照@ennuikiller的回答,我将Rscript包装在bash中。我使用pwd -P设置路径变量,它解析符号链接目录结构。然后将路径传递给Rscript。
Bash.sh
#!/bin/bash
# set path variable
path=`pwd -P`
#Run Rscript with path argument
Rscript foo.R $path
foo。R
args <- commandArgs(trailingOnly=TRUE)
setwd(args[1])
source(other.R)
令人惊讶的是R中没有“$0”类型结构!你可以通过system()调用一个用R编写的bash脚本来实现:
write.table(c("readlink -e $0"), file="scriptpath.sh",col=F, row=F, quote=F)
thisscript <- system("sh scriptpath.sh", intern = TRUE)
然后将scriptpath.sh名称拆分为other。R
splitstr <- rev(strsplit(thisscript, "\\/")[[1]])
otherscript <- paste0(paste(rev(splitstr[2:length(splitstr)]),collapse="/"),"/other.R")
你可以在一个bash脚本中包装r脚本,并检索脚本的路径作为bash变量,如下所示:
#!/bin/bash
# [environment variables can be set here]
path_to_script=$(dirname $0)
R --slave<<EOF
source("$path_to_script/other.R")
EOF