【问题标题】:Cancel xargs loop command without exit loop取消 xargs 循环命令而不退出循环
【发布时间】:2021-12-17 19:10:46
【问题描述】:

我的 bash 脚本中有两个函数示例,顺便说一句,我大部分时间都在 zsh 上工作,以防我的问题受到影响。

首先 我在第一个脚本中声明了以下函数

cancel() {
        echo -e "\nCancelling command."
}

然后我执行下面的例子。

有趣1

my_fun_xargs(){
    trap cancel SIGINT
    xargs -n1 -P 5 -I {} sh -c "command {}" < test.txt
}

乐趣2

my_fun_for(){
    trap cancel SIGINT
    for url in $(cat test.txt);
        do
        command $url ;
    done
}

所以这个脚本包含很多应该一个接一个运行的函数。 所以每个函数都包含命令列表,其中大部分是循环使用 for 或 xargs 来加快进程。 我的问题有时是函数内部的命令由于某种原因挂起或者我现在需要转义它所以我把命令trap cancel SIGINT 直到外壳取消命令而不是循环本身,这可能在 FOR LOOP 中工作。

Q 是为什么它在 xargs 中不起作用并退出整个命令。

xargs 中是否有任何特殊参数可以接受键盘解释器 ctrl c 作为取消循环中的当前命令而不是 while xargs 循环命令。

谢谢

【问题讨论】:

  • 我看不出您大部分时间使用的shell 与您作为bash 运行的脚本中的问题有什么关系。我可以建议您删除您的 zsh 标签。另外,我看不到您是如何运行脚本的,也看不到在其中运行功能的方式。我建议您将echo version=$BASH_VERSION 作为函数中的第一个命令并告诉我们您得到的输出。
  • 您指定在收到 SIGINT 后,将执行名为 cancel 的程序。你是如何验证cancel 没有运行的?
  • 我忘了提到命令cancel 它只是一个带有命令回显的函数,用于打印我现在正在取消命令。
  • 我做的另一件事是标记 zsh,以防我需要知道与陷阱相关的不同行为或与在不制动循环的情况下转义 xargs 相关的事情,我认为这没有任何问题!
  • command 是文字关键字command,还是用它来表示通用命令?

标签: bash shell for-loop zsh xargs


【解决方案1】:

这个问题缺少很多细节,所以我在推测。

当你写作时:

my_fun_xargs(){
    trap cancel SIGINT
    xargs -n1 -P 5 -I {} sh -c "command {}" < test.txt
}

xargs 终止之前,shell 不会对接收到的任何 SIGINT 进行操作。如果xargs 运行的命令没有正常(或快速)终止,则可能需要一些时间。您也许可以使用xargs ... &amp; wait 缓解该问题,这将导致外壳更快地对 SIGINT 做出反应。但这并不能解决根本问题,这似乎是 xargs 调用的进程没有响应信号快速终止。

【讨论】:

  • 这是由于 -P 选项,还是 xargs 的一般行为?我曾期望 bash 会将 SIGINT 转发给所有子进程,因此 xargs 应该会收到它。我在 xargs 手册页中发现只有在 SIGUSR1SIGUSR2 信号的情况下,并且只有在使用 -P 时才进行特定处理(xargs 永远不会终止其命令)。没有提及其他信号。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-26
  • 1970-01-01
  • 2022-01-13
  • 2012-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多