Rscript 检测 R 脚本是否来自另一个脚本 called/sourced
Rscript detect if R script is being called/sourced from another script
我编写了一个脚本,当它被获取时检查脚本是否正在 运行 交互地使用 interactive()
。如果是 运行 交互,它不会搜索命令行参数。但是,如果不是 运行 交互,它会搜索命令行参数并抛出错误。
这通常没问题,但有时我会编写第二个 R 脚本,我想 运行 独立地处理一些数据。所以 Script2 获取 Script1,Script1 检测到它没有被 运行 交互,并开始搜索命令行参数并抛出错误。
除了 interactive()
之外,还有其他方法可以让脚本检测其上下文吗?例如,当它被 运行 直接与加载它以访问其内部功能之一时,我会想要单独的行为。有了包,我可以做类似 dplyr::arrange()
的事情来访问 arrange
,而不必加载所有的 dplyr。
编辑:我当前的非常糟糕 解决方法是启动交互式会话,源脚本 1,使用 save.image()
保存函数,然后在脚本 2 中使用 load
加载保存的 .RData 文件。但显然这并不……优雅。
我不认为我使用的确切代码是相关的,但包括它以防有人认为这对答案很重要...
精简示例代码:
#!/usr/bin/env Rscript
library(optparse)
function1 <- function(etc,etc) {}
function2 <- function(etc,etc) {}
if(!interactive()) {
# example call
# Rscript create_reference_file.R -c cd4cd8 -o /home/outputfolder/
option_list = list(
make_option(c('-c', '--cell'), type = 'character', default = NULL,
help = 'the name of the cell',
metavar = 'character'),
make_option(c('-o','--outdir'), type = 'character', default = NULL,
help = 'the location where you wish to store your output',
metavar = 'character'),
)
opt_parser <- OptionParser(option_list = option_list)
opt <- parse_args(opt_parser)
function1(opt); function2(opt) # etc etc, I do stuff with the opt inputs
}
编辑
好吧,这很像 python 的 __name__
把戏。 (以下先前的回答,由于历史原因保留。)
function1 <- function(etc,etc) {}
function2 <- function(etc,etc) {}
if (sys.nframe() == 0L) {
library(optparse)
# ...
}
它是人们所希望的极简主义,不需要 source
ing 脚本来了解它,而且即使在嵌套时似乎也能正常工作。
根据 Rscript: Determine path of the executing script,通过查看脚本名称可以使用其他可能的机制(需要额外的功能)。那里存在许多看似合理的(一些非常好的)解决方案,但它们都需要一个未在基础包中定义的预定义函数(或要获取的脚本中包含的重要代码)。如果你想 "assume package X is installed",那么你的脚本可能变得不可移植。
(之前的回答,建议你用上面的。)
我会把它作为 hack 抛出......它只比你的解决方法 janky 稍微少一点,但它依赖于 calling 脚本知道 called 脚本正在测试什么。
如果调用ing脚本设置一个变量:
BEING_SOURCED_FROM_SOMEWHERE <- TRUE
然后调用ed 脚本可以检查它:
function1 <- function(etc,etc) {}
function2 <- function(etc,etc) {}
if (! exists("BEING_SOURCED_FROM_SOMEWHERE")) {
library(optparse)
# ...
}
我不喜欢。它不如 python 的
灵活
if __name__ == "__main__":
import optparse
# ...
但我觉得我不喜欢它的原因还不如你使用 save
和 load
来定义函数。
我编写了一个脚本,当它被获取时检查脚本是否正在 运行 交互地使用 interactive()
。如果是 运行 交互,它不会搜索命令行参数。但是,如果不是 运行 交互,它会搜索命令行参数并抛出错误。
这通常没问题,但有时我会编写第二个 R 脚本,我想 运行 独立地处理一些数据。所以 Script2 获取 Script1,Script1 检测到它没有被 运行 交互,并开始搜索命令行参数并抛出错误。
除了 interactive()
之外,还有其他方法可以让脚本检测其上下文吗?例如,当它被 运行 直接与加载它以访问其内部功能之一时,我会想要单独的行为。有了包,我可以做类似 dplyr::arrange()
的事情来访问 arrange
,而不必加载所有的 dplyr。
编辑:我当前的非常糟糕 解决方法是启动交互式会话,源脚本 1,使用 save.image()
保存函数,然后在脚本 2 中使用 load
加载保存的 .RData 文件。但显然这并不……优雅。
我不认为我使用的确切代码是相关的,但包括它以防有人认为这对答案很重要...
精简示例代码:
#!/usr/bin/env Rscript
library(optparse)
function1 <- function(etc,etc) {}
function2 <- function(etc,etc) {}
if(!interactive()) {
# example call
# Rscript create_reference_file.R -c cd4cd8 -o /home/outputfolder/
option_list = list(
make_option(c('-c', '--cell'), type = 'character', default = NULL,
help = 'the name of the cell',
metavar = 'character'),
make_option(c('-o','--outdir'), type = 'character', default = NULL,
help = 'the location where you wish to store your output',
metavar = 'character'),
)
opt_parser <- OptionParser(option_list = option_list)
opt <- parse_args(opt_parser)
function1(opt); function2(opt) # etc etc, I do stuff with the opt inputs
}
编辑
好吧,这很像 python 的 __name__
把戏。 (以下先前的回答,由于历史原因保留。)
function1 <- function(etc,etc) {}
function2 <- function(etc,etc) {}
if (sys.nframe() == 0L) {
library(optparse)
# ...
}
它是人们所希望的极简主义,不需要 source
ing 脚本来了解它,而且即使在嵌套时似乎也能正常工作。
根据 Rscript: Determine path of the executing script,通过查看脚本名称可以使用其他可能的机制(需要额外的功能)。那里存在许多看似合理的(一些非常好的)解决方案,但它们都需要一个未在基础包中定义的预定义函数(或要获取的脚本中包含的重要代码)。如果你想 "assume package X is installed",那么你的脚本可能变得不可移植。
(之前的回答,建议你用上面的。)
我会把它作为 hack 抛出......它只比你的解决方法 janky 稍微少一点,但它依赖于 calling 脚本知道 called 脚本正在测试什么。
如果调用ing脚本设置一个变量:
BEING_SOURCED_FROM_SOMEWHERE <- TRUE
然后调用ed 脚本可以检查它:
function1 <- function(etc,etc) {}
function2 <- function(etc,etc) {}
if (! exists("BEING_SOURCED_FROM_SOMEWHERE")) {
library(optparse)
# ...
}
我不喜欢。它不如 python 的
灵活if __name__ == "__main__":
import optparse
# ...
但我觉得我不喜欢它的原因还不如你使用 save
和 load
来定义函数。