后台管道中上一个命令的 PID

后台管道中上一个命令的 PID

我有一个脚本片段:

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 独立的PID tail

相关内容