我需要检索通过管道传输到另一个进程的进程的 PID,这些进程一起作为 bash 中的后台作业生成。以前我只是依靠pgrep
,但事实证明在pgrep
能够找到该过程之前可能会有> 2s的延迟:
#!/bin/bash
cmd1 | cmd2 &
pid=$(pgrep cmd1) # emtpy in about 1/10
我发现针对这个问题的一些常见建议是使用进程替换而不是简单的管道 ( cmd1 >(cmd2) & pid=$!
) 或使用jobs
内置函数。进程替换运行整个子shell(对于整个运行时),所以我现在宁愿使用jobs
,但我想避免两次犯同样的错误......
jobs
如果我在生成它们后立即执行查找,我可以 100% 依赖于了解这两个进程吗?
#!/bin/bash
cmd1 | cmd2 &
pid=$(jobs -p %cmd1) # 10/10?
这可能是由于在后台运行作业,或者可能是一个怪癖set -x
,但以下示例通常以任何顺序列出执行的命令。到目前为止,输出似乎是正确的,但我想完全排除在jobs
作业开始之前jobs
可以执行的可能性(或者至少不会列出两个进程)!?jobs
#!/bin/bash
set -x
tail -f /dev/null | cat &
jobs -l
kill %tail
例子:
+ jobs -l
[1]+ 2802325 Running tail -f /dev/null
2802326 | cat &
+ tail -f /dev/null
+ kill %tail
同样,在流程替换的情况下,我可以依靠pid=$!
始终工作吗?它到底是为了“扩展到最近执行的后台(异步)命令的进程ID”而设计的?