因此,我有一个在最近停止工作的 exec 行中使用进程替换的 bash 命令,它可以归结为以下示例:
script.sh的内容:
#!/bin/bash
ls -l "$1" >/tmp/out
echo "SUCCESS" > "$1"
这有效,将“SUCCESS”放入log
:
rm -f log; ./script.sh >(cat >log)
使用tail
也有效:
rm -f log; ./script.sh >(tail >log)
exec
与cat
作品 一起使用:
rm -f log; exec ./script.sh >(cat >log)
但是..exec
与tail
确实不是工作:
rm -f log; exec ./script.sh >(tail >log)
在所有情况下,/tmp/out 的内容看起来都不错,如下所示:
l-wx------ 1 user user 64 Oct 14 10:55 /dev/fd/63 -> pipe:[158518]
为什么可以cat
工作但不能tail
or head
?这在过去的某个时候是有效的..这是 bash 功能更改还是 bug 回归..?
bash --version: GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)
答案1
因此,在替换进程上使用strace
表明,在它们有机会写入之前,我们从内核收到了 SIGHUP tail
。head
一个简单的解决方法是添加nohup
替换:
rm -f 日志; exec ./script.sh >(nohup tail >log)
我想我明白为什么 exec 会失败。 IIUC, >(tail >log) 创建当前进程的子进程bash
。然而,当使用 exec 时,它现在成为script.sh
.当 script.sh 退出时,内核将其发送SIGHUP
给所有子进程。
仍然不确定为什么这会起作用,也许在较新的内核版本中,它发送 SIGHUP 的速度更快/更积极。