我有一个脚本片段:
MyCoolCommand 2>&1 | tail -n 256 > "report.out" &
cool_pid=$! # FIXME
它有一个错误 -cool_pid
是 的 PID tail
。管道在后台运行。如何保存cool_pid
的 PID MyCoolCommand
?shell 是 /bin/sh。如果使用旧的普通 /bin/sh 无法实现,我准备切换到 Bash,如果有办法实现它。
答案1
在 Bash 中,你可以使用进程替换:
MyCoolCommand > >(tail -n 256 > report.out) 2>&1 &
cool_pid=$!
数据将从流到MyCoolCommand
类似于tail
您的原始命令,但$!
将是您想要的。
笔记:
2>&1
需要在之后>
。- shell 会在退出后立即认为任务已完成
MyCoolCommand
,而tail
可能仍在运行。如果您的脚本在某个时候wait
为工作而准备,然后report.out
进一步处理,请记住文件可能尚未准备好。为了比较:您的脚本MyCoolCommand | tail … &
在以下情况下被视为完成两个都进程退出。
您可以简单地解决问题sh
,但这需要手动管道:
mkfifo myfifo
<myfifo tail -n 256 >report.out &
MyCoolCommand >myfifo 2>&1 &
cool_pid=$!
rm myfifo
笔记:
在 fifo 仍在使用时将其删除是安全的。尽管它已从目录中取消链接,但程序仍将继续使用它。只有当 fifo 不再使用时,操作系统才会真正销毁它。新命名的文件
myfifo
(如果曾经创建过)与旧文件没有任何关系(名称除外),即使旧文件仍在使用中。如果名为的文件
myfifo
已在当前工作目录中(因为脚本的另一个实例并行运行;或出于其他原因)并且可能正在使用中,则脚本可能会出现错误。正确的做法是创建一个临时目录并mktemp -d
在其中放置一个 fifo。mktemp
不可移植。通过这种方法,你可以保存
MyCoolCommand
和独立的PIDtail
。