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)
    # ...
}

它是人们所希望的极简主义,不需要 sourceing 脚本来了解它,而且即使在嵌套时似乎也能正常工作。

根据 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
    # ...

但我觉得我不喜欢它的原因还不如你使用 saveload 来定义函数。