kill -INT pid无法杀死ksh脚本中的进程

时间:2014-08-04 06:56:37

标签: signals ksh sigint

两种情况:

  1. 在CLI中运行命令

    zfs发送rpool / fs @ snap | zfs recv rpool / fs1 @ snap&

    [1] 139781

    ps -ef | grep zfs

        root 139783 119679   0 23:28:34 kz/term/2    0:00 grep zfs
        root 139781 119679   3 23:28:30 kz/term/2    0:02 zfs recv rpool/fs1@snap
        root 139780 119679   3 23:28:30 kz/term/2    0:03 zfs send rpool/fs@snap
    

    kill -INT 139780

    ps -ef | grep zfs

        root 139781 119679   7 23:28:30 kz/term/2    0:08 zfs recv rpool/fs1@snap
        root 139785 119679   0 23:28:42 kz/term/2    0:00 grep zfs
    
  2. 我们可以看到当前的shell(119679)创建了两个 孩子(139780& 139781)和kill -INT可以打断 139780成功。

    1. 现在我们编写了一个ksh脚本来完成几乎相同的工作

      cat a.sh

      #!/usr/bin/ksh -p
      echo $$
      zfs send rpool/fs@snap | zfs recv rpool/fs1@snap &
      pid=$(ps -ef|grep 'zfs send rpool/fs@snap'|grep -v grep | awk '{print $2}')
      /usr/bin/kill -s INT $pid
      sleep 1
      ps -ef|grep zfs
      

      ./ a.sh

      139788
          root 139791 139789   1 23:30:57 kz/term/2    0:01 zfs send rpool/fs@snap
          root 139789 139788   1 23:30:57 kz/term/2    0:01 zfs recv rpool/fs1@snap
          root 139798 139788   0 23:30:58 kz/term/2    0:00 grep zfs
      
    2. 现在a.sh分叉139789和139789分叉139791,在这种情况下, a.sh调用kill命令将SIGINT发送到139791,但失败了。

      为什么a.sh不会发送' zfs发送'处理? (在bash脚本中,a.sh分叉发送和接收进程)? 为什么杀死-s INT未能中断' zfs发送'处理? 如何在ksh脚本中中断发送过程?

      非常感谢。

1 个答案:

答案 0 :(得分:0)

你有一个嵌套分叉的原因是因为你正在使用'&' - 管理管道进程,这意味着管道中的第一个命令分叉第二个,而不是shell进程。不幸的是,我目前没有zfs可以使用,因此我无法检查zfs在进程组中的播放方式,但嵌套分叉是管道后台进程的默认行为。

SIGINT 无法处理您的父进程,因为符合POSIX标准的父进程在终止自身之前只会等待 SIGCHLD ,而忽略 SIGINT SIGQUIT

如果您使用 SIGTERM

/usr/bin/kill -s TERM $pid 

您的进程将处理信号,并正常终止。 在“zfs'”的缺席中,我使用'尾部模拟了您的管道流程:

#!/usr/bin/ksh -p
echo $$
#zfs send rpool/fs@snap | zfs recv rpool/fs1@snap &
tail -f foo | tail -f &
#pid=$(ps -ef|grep 'zfs send rpool/fs@snap'|grep -v grep | awk '{print $2}')
pid=$(ps -ef|grep "t[a]il"| awk '{print $2}')
#/usr/bin/kill -s INT $pid
/usr/bin/kill -s TERM $pid
echo $?
sleep 1
ps -ef|grep "t[a]il"

希望有所帮助。