繁体   English   中英

将命令通过管道传递给 shell 脚本时,为什么退出管道命令会使 shell 脚本退出?

[英]When piping a command to shell script, why does exiting piped command makes shell script exit?

首先,对不起,如果标题不清楚或具有误导性,我的问题并不是很容易断章取意地理解。

所以这里是:我正在运行一个 shell 脚本(hello.sh),它需要将自身从/root重新定位到/ 因此,我进行了一个简单的递归,从脚本运行的位置进行测试,并制作临时副本并启动并退出(最后一个临时副本将移动原始文件,并在仍在运行时删除自身)。

#!/bin/sh    

IsTMP=$(echo $0 | grep "tmp")
if [ -z "$IsTMP" ]; then
        cp /root/hello.sh /tmp/hello.sh
        /bin/sh /tmp/hello.sh &
        exit
else
        unlink /hello.sh
        rsync /root/hello.sh /hello.sh
        rm /root/hello.sh
        rm /tmp/hello.sh
fi


while true; do
        sleep 5
        echo "Still Alive"
done

这个脚本运行良好并且符合我的需要(即使它是一个可怕的黑客):脚本被移动,并从一个临时位置重新执行。 但是,当我使用 T 恤通过管道传输 shell 脚本时,就像:

/hello.sh | tee -a /log&

行为不一样:

  • hello.sh正在退出但不是tee
  • 当我尝试杀死tee时,临时副本在几秒钟后自动杀死,不会进入无限循环

如果我将 tee 替换为另一个二进制文件(例如 watch,...),这种行为是完全相同的,所以我想知道它是否来自管道。

对不起,如果我不太清楚我的问题。 提前致谢。

当我尝试杀死tee时,临时副本在几秒钟后自动杀死,不会进入无限循环

事实并非如此。 脚本正在进入无限循环,这几秒钟循环中sleep 5暂停的sleep 5,然后它被信号 SIGPIPE(Broken pipe)杀死,因为它试图向关闭的管道echo "Still Alive"由于tee已被杀死,因此在阅读结束时。

tee 和第二个实例之间没有链接

事实并非如此。 有一个链接,即管道,其写端是父shell脚本以及(继承)子shell脚本的标准输出,读端是tee的标准输入。 /fd , where is the process id of the script's shell on the one hand, and of tee on the other.如果您查看ls -l /proc/ /fd ,您可以看到这一点,其中一方面是脚本 shell 的进程 ID,另一方面是tee的进程 ID。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM