中断循环与系统命令

Joh*_*lby 16 r

我正在越来越多地使用Rscript,我通常会使用bash脚本.一个小烦恼是,许多这些脚本循环一些system()调用,如果我试图中断它,R基本上没有时间来捕获我的控制-c.相反,它只是中止正在运行的系统命令并继续下一个循环迭代.例如,当我尝试通过按住control-c来中断以下操作时,它仍然会通过所有迭代:

for(i in 1:10) {
  cat(i)
  system('sleep 3')
}
Run Code Online (Sandbox Code Playgroud)

到目前为止,我总是通过在每个循环中插入一个小暂停来解决这个问题

for(i in 1:10) {
  Sys.sleep(0.25)
  cat(i)
  system('sleep 3')
}
Run Code Online (Sandbox Code Playgroud)

如果我按住control-c,这将让我在一两次迭代中中止,但我想知道,有没有更有效的方法来实现这种行为?

Ite*_*tor 4

约翰,我不确定这是否有帮助,但通过调查setTimeLimit,我了解到只要用户能够执行中断(例如 Ctrl-C),它就可以停止执行。请参阅此问题以获取一些参考资料。

特别是,回调可能是一种可行的方法,我会在developer.r-project.org上查看本addTaskCallback指南。

以下是其他四项建议:

  1. 虽然这是一种 hack,但我可以采用一种非常不同的方法来调用两个 R 会话,一个是主会话,另一个只是为了执行主会话传递的 shell 命令,它只等待确认工作已完成,然后再开始下一个。

  2. 如果您可以使用foreach替代for(并行,通过%dopar%,或串行%do%而不是%dopar%或仅使用1个注册工人),这可能更容易受到干扰,因为它可能相当于第一个建议(因为它分叉了 R)。

  3. 如果您可以检索外部命令的退出代码,则可以将其传递给循环条件。 之前的问答在这方面会有所帮助。

  4. 如果您想让所有内容都在 bash 脚本中运行,那么 R 可以只编写一个长脚本(即将一个字符串或一系列字符串输出到文件中)。这可以被执行,并且保证中断不会影响循环,因为您已经展开了循环。或者,您可以在 bash 中编写循环。 以下是示例find就我个人而言,我喜欢使用(例如)将命令应用于文件find .... -exec doStuff {} ';'或通过反引号作为输入。不幸的是,我不能轻易地在 SO 上给出格式良好的代码,因为它在反引号中嵌入了反引号... 请参阅此页的示例 因此,可能的情况是您可以有一个命令,没有循环,并应用一个命令函数适用于满足一组特定条件的所有文件。对于 bash 用户来说,通过反引号使用命令替换是一个非常方便的技巧。