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

时间:2017-12-13 14:17:09

标签: linux shell sh

首先,如果标题不清晰或具有误导性,我很抱歉,我的问题并非不容易理解。

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

#!/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

这个脚本非常适合我的需求(即使它是一个可怕的黑客):脚本被移动,并从临时位置重新执行。但是,当我使用tee管道shell脚本时,就像:

/hello.sh | tee -a /log&

行为不一样:

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

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

很抱歉,如果我不太清楚我的问题。 提前谢谢。

1 个答案:

答案 0 :(得分:0)

  

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

事实并非如此。脚本正在进入无限循环几秒钟是循环暂停中sleep 5的五秒钟,然后被杀死 >由信号SIGPIPE(断开的管道)引起,因为它试图echo "Still Alive"到由于tee被杀死而在读取端关闭的管道。

  

Tee与第二个实例之间没有链接

事实并非如此。有一个链接,即管道,其写端是父级以及(继承)子级shell脚本的标准输出,而读端是tee的标准输入。如果您查看ls -l /proc/pid/fd,就会看到这一点,其中 pid 一方面是脚本外壳的进程ID,另一方面是tee的进程ID。