无法使用Ctrl + c终止Shell命令 [英] Cannot terminate a shell command with Ctrl+c

查看:1084
本文介绍了无法使用Ctrl + c终止Shell命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以告诉我为什么 Ctrl + c 不能正确终止bash语句吗?

Would someone please tell me why below bash statement cannot be terminated by Ctrl+c properly?

$( { ( tail -fn0 /tmp/a.txt & )| while read line; do echo $line; done } 3>&1 )

我运行此语句,然后启动两个bash进程和一个tail进程(从ps auxf获取),然后输入 Ctrl + c ,它不会退出到在bash提示符下,此时,我看到两个bash进程停止了,而tail仍在运行,然后在/tmp/a.txt中输入了一些内容,然后我们进入了bash提示符.

I run this statement, then two bash processes and one tail process are launched(got from ps auxf), then input Ctrl+c, and it won't quit to the bash prompt, at this moment, I see the two bash processes stopped, while the tail is still running, then I input something into /tmp/a.txt, then we could get into bash prompt.

我想要的是,输入 Ctrl + c ,然后直接退出bash提示符而没有任何相关过程.

What I want is, input Ctrl+c, then just quit into bash prompt without any relevant process left.

有人解释此语句的确切过程会更有意义,例如用管道导致bash分支,将某些内容重定向到某个地方等.

It will be more appreciative that someone explains the exact process of this statement, like a pipe causes the bash fork, something redirect to somewhere, etc.

2014年10月9日更新:

在此提供一些更新,以防对您有用. 我采用的解决方案与以下两个因素相似:

Here provide some update in case it's useful to you. My adopt solution is alike with 2 factors:

  1. 使用tmp pid文件

  1. use a tmp pid file

( tail -Fn0 ${monitor_file} & echo "$!" >${tail_pid} ) | \
while IFS= read -r line; do 
    xxxx
done 

  • 使用陷阱,例如:trap "rm ${tail_pid} 2>/dev/null; kill 0 2>/dev/null; exit;" INT TERM杀死相关进程并删除剩余文件.

  • use trap like: trap "rm ${tail_pid} 2>/dev/null; kill 0 2>/dev/null; exit;" INT TERM to kill relevant processes and remove remain files.

    请注意,此kill 0 2是特定于bash的,0表示当前进程组中的所有进程. 此解决方案使用了tmp pid文件,而我仍然希望其他没有tmp pid文件的解决方案.

    Please note, this kill 0 2 is bash specific, and 0 means all processes in the current process group. This solution used a tmp pid file, while I still expect other solution without tmp pid file.

    推荐答案

    它可以捕获INT信号(由Ctrl-C发送)以杀死tail进程.

    It works to trap the INT signal (sent by Ctrl-C) to kill the tail process.

    $( r=$RANDOM; trap '{ kill $(cat /tmp/pid$r.pid);rm /tmp/pid$r.pid;exit; }' SIGINT EXIT; { ( tail -fn0 /tmp/a.txt & echo $! > /tmp/pid$r.pid  )| while read line; do echo $line; done } 3>&1 )
    

    (我在PID文件名上使用了随机值,至少在大多数情况下允许多个实例运行)

    (I use a random value on the PID file name to at least mostly allow multiple instances to run)

    这篇关于无法使用Ctrl + c终止Shell命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆