以下bash脚本在循环中分叉几个进程,沿途收集所有PID,然后等待它们全部完成:
PIDS=''
for i in $(seq 1 3); do
./longRunningProcess &
PIDS=$PIDS' '$!
done
wait $PIDS
这个在bash中逐行输入时工作正常,但是我想在一行上执行for循环,我认为应该如下:
for i in $(seq 1 3); do ./longRunningProcess & PIDS=$PIDS' '$!; done
但是当我尝试执行此操作时,我得到:
-bash: !: event not found
似乎bash以某种方式解释了!作为命令历史扩展,但我认为前面的$
会将其解释更改为最后一个分叉后台进程的PID。
我想了解:
!
谢谢!
答案 0 :(得分:1)
历史扩张是愚蠢的。
问题不在于单线问题是启用了历史扩展(主要是)。
在交互式shell中禁用历史记录扩展可以使其正常工作。
将单行放在脚本中(默认情况下禁用历史记录扩展)也可以。
历史扩张和单线的结合导致扩张被尝试和爆炸。
在shell中的多行上执行此操作也会失败(如果你让分号保持完整......在一秒内更多内容)。
bash参考手册的History Expansion部分解释了如何扫描命令行以进行历史记录扩展:
历史扩展是由历史扩展字符的外观引入的,默认情况下为“!”。只有'\'和'''可用于转义历史记录扩展字符。
bash man page添加了(我不确定为什么参考手册没有说明这一点):
如果在历史记录扩展字符后面立即找到,则有几个字符会禁止历史记录扩展,即使它没有引用:空格,制表符,换行符,回车符和=。如果启用了extglob shell选项,(也将禁止扩展。
所以添加一个空格/等。在该单行版本的!
之后应该有效。