【问题标题】:Copy script after executing执行后复制脚本
【发布时间】:2015-07-14 13:38:44
【问题描述】:

是否有可能将执行的行或基本上是脚本复制到工作目录中?

所以我的正常情况是,我有一个独立的脚本,它只需要在工作目录中获取,他们会做我需要的一切。 几个月后,我对这些脚本进行了更新,我希望在执行源代码时获得脚本的快照...

所以基本上是file.copy(ITSELF, '.') 或类似的东西。

【问题讨论】:

  • 也许你可以稍微改变你的方法并使用一个小的帮助脚本来做类似file.copy("myscript.r", paste0("snapshot_", Sys.Date(),"_myscript.r")); source("myscript.r")
  • 我猜会起作用,但是没有获取它自己的文件名和路径的功能吗?我以为我在 python 中使用了类似的东西,但这是使用命令行。在那里我可以得到第一个参数(文件名)。我想知道来源是否不能返回这样的东西......
  • 如果 Python 中有这样的函数,我不会感到惊讶,因为 Python 在类定义中提供了有用的元功能,例如 __self__ 属性。我不知道您在 R 中描述的上述内容 (file.copy(ITSELF, '.')),但其他人可能有更好的解决方案。
  • 我刚刚通过link 找到了一个提示,但他们已经说它有点不稳定,但目前它似乎有效。所以建议使用sys.frame(1)$ofile。但老实说,我不明白这一点,因为 sys.frame 无法以某种方式访问​​。

标签: r


【解决方案1】:

我想这就是你要找的东西:

file.copy(sys.frame(1)$ofile,
          to = file.path(dirname(sys.frame(1)$ofile),
                         paste0(Sys.Date(), ".R")))

这将获取当前文件并将其复制到同一目录中名为 currentDate.R 的新文件中,例如2015-07-14.R

如果要复制到工作目录而不是原始脚本目录,请使用

file.copy(sys.frame(1)$ofile,
          to = file.path(getwd(),
                         paste0(Sys.Date(), ".R")))

请注意,sys.frame(1)$ofile 仅在获取保存的脚本时才有效,尝试在终端中运行它会失败。值得一提的是,这可能不是最佳实践。或许研究一下版本控制系统会更好。

解释:

TBH,我可能不是解释这一点的最佳人选(我从某个地方复制了这个想法并有时使用它),但我会尝试。基本上,为了获得有关脚本文件的信息,R 需要将其作为具有该信息的环境中的文件运行,并且当该环境是 source 调用时,它包含 ofile 数据。我们使用(1) 来选择全局环境(即0)之后的下一个(source()'s)环境。当您从终端运行它时,除了 Global 之外没有其他框架/环境(这是错误消息),因为没有文件正在运行 - 命令直接发送到终端。

为了说明这一点,我们可以做一个简单的测试:

> sys.frame(1)
Error in sys.frame(1) : not that many frames on the stack

但是如果我们从另一个函数中调用它:

> myf <- function() sys.frame(1)
> myf()
<environment: 0x0000000013ad7638>

我们函数的环境中没有任何东西,所以它存在,但在这种情况下,没有ofile

> myf <- function() names(sys.frame(1))
> myf()
character(0)

【讨论】:

  • 感谢 Molx,这是我刚刚发现的,但我不完全了解 sys.frame 函数。你能解释一下吗?为什么不能在终端中使用?
  • @drmariod 我在答案中添加了一些信息。
  • 感谢您提供更多信息。我想通了,还有变量filenamesrcfile 似乎有相同的信息......无论如何,我会选择ofile,因为我也找到了一些使用它的建议。感谢您的解决方案。
  • 对于交互式你可以使用 utils::savehistory: stat.ethz.ch/R-manual/R-devel/library/utils/html/… 。更好的是开始使用 git、subversion 或类似的版本控制。
【解决方案2】:

我只是想添加我的解决方案,因为我决定在执行复制命令之前使用try 函数...因为我感觉我错过了一些控制...

try({
  script_name <- sys.frame(1)$ofile
  copy_script_name <- 
    paste0(sub('\\.R', '', basename(script_name)),
           '_',
           format(Sys.time(), '%Y%m%d%H%M%S'),
           '.R')
  file.copy(script_name,
            copy_script_name)
})

这会将脚本复制到当前目录并在文件名中添加时间戳。万一出现问题,脚本的其余部分仍将执行。

【讨论】:

    【解决方案3】:

    我最初发布了另一个帖子,我认为它解决了您的问题:https://stackoverflow.com/a/62781925/9076267

    在我的例子中,我需要一种方法来复制执行文件以备份原始 > 脚本及其输出。这在研究中是比较重要的。 在命令行上运行我的脚本时对我有用的是>此处介绍的其他解决方案的混合,如下所示:

    library(scriptName)
    file_dir <- paste0(gsub("\\", "/", fileSnapshot()$path, fixed=TRUE))
    file.copy(from = file.path(file_dir, scriptName::current_filename()) ,
              to = file.path(getwd(), scriptName::current_filename()))
    

    或者,可以在文件名中添加日期和我们以帮助>将文件与源区分开来,如下所示:

    file.copy(from = file.path(current_dir, current_filename()) ,
              to = file.path(getwd(), subDir, paste0(current_filename(),"_", Sys.time(), ".R")))
    
    

    【讨论】:

    • 问题要求将脚本复制回工作目录。我看到有些部分可能是相关的。你能尝试解决这个问题而不是大量复制它吗?非常感谢
    • @StupidWolf 如果要将运行脚本复制到工作目录,只需设置new_dir &lt;- getwd()。我会将修改添加到我的答案中。但是,如果您只是在谈论将部分脚本复制到新文件中,那么它就行不通了。但我想问题是关于复制整个脚本,对吧?
    猜你喜欢
    • 1970-01-01
    • 2013-02-17
    • 1970-01-01
    • 2012-09-14
    • 2017-01-14
    • 1970-01-01
    • 1970-01-01
    • 2020-07-14
    • 1970-01-01
    相关资源
    最近更新 更多