Linux - 在后台同时执行 shell 个脚本并知道何时完成

Linux - Execute shell scripts simultaneously on the background and know when its done

我正在使用 rsync 将文件从一台服务器传输到另一台服务器(均归我所有),我唯一的问题是这些文件超过 50GB,我需要传输大量文件(其中超过 200 个)。 现在我可以打开多个选项卡和 运行 rsync 或在脚本末尾添加“&”以在后台执行它。

所以我的问题是,如何在后台执行此命令,当它完成传输后,我希望在执行脚本的终端 window 上显示一条消息。

(rsync -av -progress [FOLDER_NAME] [DISTINATION]:[PATH] &) && echo 'Finished'

我知道那是完全错误的,但我需要在后台使用 & 来 运行 它,并在 rsync 完成后使用 && 来 运行 回显。

您可以为此使用 gnu screen,screen 可以 monitor 输出静音和 activity。额外的好处 - 您可以关闭终端并稍后重新连接到屏幕 - 如果您 运行 可以在服务器上进行屏幕就更好了 - 然后您可以关闭或重新启动您的机器并且屏幕中的进程仍在执行。

除了基于 screen 的解决方案,您还可以使用 xargs 工具。

echo '/srcpath1 host1 /dstpath1
    /srcpath2 host2 /dstpath2
    /srcpath3 host3 /dstpath3'| \
xargs -P 5 --max-lines 1 bash -e 'rsync -av -progress  :'

xargs 读取标准输入的输入,并为每个单词或行执行一个命令。这次,行。

它的优势在于:它可以并行执行 child 进程!在此配置中,xargs 通过始终使用 5 个并行 child 进程来执行此操作。这个数字可以是1,甚至可以是无穷大。

xargs 将退出,如果它的所有 child 都准备就绪,并且可以很好地处理每个 ctrl/c、child 处理等,并且可以容忍问题。

而不是 echoxargs 的输入可以来自文件,甚至也可以来自管道中的先前命令。或者来自 forwhile 循环。

好吧,为了回答你的具体问题,你的调用:

(rsync ... &) && echo 'Finished'

创建一个子外壳 - ( ... ) 位 - 其中 rsync 在后台 运行,这意味着子外壳将在启动后立即退出 rsync,而不是在 rsync 完成之后。 && echo ... 部分然后注意到子 shell 已成功退出并执行其操作,这不是您想要的,因为 rsync 很可能仍然是 运行ning.

要完成你想要的,你需要这样做:

(rsync ... && echo 'Finished') &

这会将子 shell 本身置于后台,子 shell 将 运行 rsync 然后 echo。如果您需要在稍后的脚本中等待该子 shell 完成,只需在适当的位置插入 wait

你也可以这样构造它:

rsync ... &
# other stuff to do while rsync runs
wait
echo 'Finished'

哪个是"better"真的只是一个偏好问题。只有在 rsync 不报告错误退出代码时 && 才会 运行 echo 有一个细微差别 - 但将 && 替换为 [=26] =] 会使这两个模式更等价。第二种方法使 echo 与脚本的其他输出同步,因此它不会出现在其他输出的中间,因此从这方面来看它可能稍微更可取,但捕获 [= 的退出条件14=] 如果有必要的话会更复杂...