当前位置:  开发笔记 > 编程语言 > 正文

bash:在后台启动多个链式命令

如何解决《bash:在后台启动多个链式命令》经验,为你挑选了5个好方法。

我试图在后台使用bash在paralel中运行一些命令.这是我正在尝试做的事情:

forloop {
  //this part is actually written in perl
  //call command sequence
  print `touch .file1.lock; cp bigfile1 /destination; rm .file1.lock;`;
}

反引号(``)之间的部分产生一个新的shell并连续执行命令.问题是,只有在执行完最后一个命令后,对原始程序的控制才会返回.我想在后台执行整个语句(我不期待任何输出/返回值),我想循环继续运行.

调用程序(具有循环的程序)在所有生成的shell完成之前不会结束.

我可以在perl中使用线程来生成调用不同shell的不同线程,但它似乎有点过分......

我可以启动一个shell,给它一组命令并告诉它去后台吗?



1> Hugh Allen..:

我没有测试过这个但是怎么样

print `(touch .file1.lock; cp bigfile1 /destination; rm .file1.lock;) &`;

括号表示在子shell中执行但不应该受到伤害.


你不想要打印或反引号 - 即使这些命令确实提供了有用的输出在后台运行它们也意味着反引号看不到它
非常感谢!它还帮助我解决了一个不同的问题,使用bash脚本,其中一些对外部进程的调用仍在stdout中打印输出,即使我使用"&>/dev/null",但解决了调用方式:\`(./ call_the_proccess &>/dev/null)&\`
(我不喜欢反叛,我发现$()更容易阅读,但这与此无关)

2> Mad_Ady..:

谢谢休,这样做了:

adrianp@frost:~$ (echo "started"; sleep 15; echo "stopped")
started
stopped
adrianp@frost:~$ (echo "started"; sleep 15; echo "stopped") &
started
[1] 7101
adrianp@frost:~$ stopped

[1]+  Done                    ( echo "started"; sleep 15; echo "stopped" )
adrianp@frost:~$ 

其他想法不起作用,因为它们在后台启动每个命令,而不是命令序列(这在我的情况下很重要!).

再次感谢你!


除了调试一点时间外,你不会"睡3"

3> lechup..:

另一种方法是使用以下语法:

{ command1; command2; command3; } &
wait

请注意,它&位于命令组的末尾,而不是在每个命令之后.最后一个命令之后的分号是必要的,第一个括号之后和最后一个括号之前的空格也是必需的.所述wait在端部保证了衍生的子进程(命令组)结束之前父进程不杀死.

你也可以做重定向stderr等奇特的东西stdout:

{ command1; command2; command3; } 2>&2 1>&1 &

你的例子看起来像:

forloop() {
    { touch .file1.lock; cp bigfile1 /destination; rm .file1.lock; } &
}
# ... do some other concurrent stuff
wait # wait for childs to end



4> GavinCattell..:
for command in $commands
do
    "$command" &
done
wait

命令末尾的&符号在后台运行它,wait等待后台任务完成.


不行,因为每个命令都会在后台运行,而不是命令序列.
@Gavin - 你需要**$ command**(注意"$").
如果命令包含空格这不起作用,他们通常会这样做

5> NVRAM..:

GavinCattell得到了最接近的(对于bash,IMO),但正如Mad_Ady指出的那样,它不会处理"锁定"文件.这应该:

如果还有其他待处理作业,等待也会等待.如果您需要等待只是副本,你可以积累的PID和等待只.如果没有,你可以用"pids"删除3行,但它更通用.

另外,我添加了检查以完全避免副本:

pids=
for file in bigfile*
do
    # Skip if file is not newer...
    targ=/destination/$(basename "${file}")
    [ "$targ" -nt "$file" ] && continue

    # Use a lock file:  ".fileN.lock" for each "bigfileN"
    lock=".${file##*/big}.lock"
    ( touch $lock; cp "$file" "$targ"; rm $lock ) &
    pids="$pids $!"
done
wait $pids

顺便说一句,看起来您正在将新文件复制到FTP存储库(或类似文件).如果是这样,您可以考虑复制/重命名策略而不是锁定文件(但这是另一个主题).

推荐阅读
N个小灰流_701
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有