返回信息流有一个脚本mypy.py,里面就是print和Sleep循环
还有一个脚本 mysh.sh 里面就是
nohup python mypy.py &
tail -f nohup.out
控制台执行./mysh.sh后
如果执行ctrl+z,tail结束,但python进程会进入T状态
如果执行ctrl+c,tail结束,python进程正常。
为何ctrl+C只作用在了tail上,而ctrl+Z却把python进程也给发了个挂起的信号呢?
这是一条镜像帖。来源:北邮人论坛 / linux / #159674同步于 2020/9/3
该镜像源已超过 30 天没有更新,可能在源站已被删除。
Linux机器人发帖
【问题】关于ctrl+z和ctrl+c在脚本执行中的作用范围的疑问
zithersw
2020/9/3镜像同步7 回复
订阅后,新回复会通过你的通知中心匿名送达。
7 条回复
(自我感觉好像描述的没问题,有问题请指出)
在支持 job control 的 shell 中,shell 的子进程组成的进程组分为两种,前台进程组和后台进程组。
ctrl-z 产生 sighup 信号,ctrl-c 产生 sigint 信号,当在shell里按下这两个键的时候信号会发送到前台进程组中。
按照你的例子,首先有四个进程:mysh.sh、nohup python mypy.py、python mypy.py以及 tail -f log。其中第二三个属于后台进程组,第一四个属于前台进程组,第二四个进程是第一个进程的子进程,第三个进程是第二个进程的子进程。
当按下 ctrl-z 的时候会挂起 tail 和 mysh.sh 进程,第二三个进程不受影响。当按下 ctrl-c 的时候会终止 tail 和 mysh.sh 进程,中间两个依然不受影响。当你退出当前会话后,nohup 进程的ppid会变为1。
相关知识点看 apue 的 process relationship 一章
谢谢回复,但其实,我说的是3个进程
mysh.sh中的语句是
nohup python mypy.py &
tail -f
好像解释不通
【 在 nitroethane 的大作中提到: 】
: (自我感觉好像描述的没问题,有问题请指出)
: 在支持 job control 的 shell 中,shell 的子进程组成的进程组分为两种,前台进程组和后台进程组。
: ctrl-z 产生 sighup 信号,ctrl-c 产生 sigint 信号,当在shell里按下这两个键的时候信号会发送到前台进程组中。
: ...................
> 有一个脚本mypy.py,里面就是print和Sleep循环
> 还有一个脚本 mysh.sh 里面就是
> nohup python mypy.py &
> tail -f nohup.out
>
> 控制台执行./mysh.sh后
> 如果执行ctrl+z,tail结束,但python进程会进入T状态
> 如果执行ctrl+c,tail结束,python进程正常。
>
> 为何ctrl+c之作用在tail上,而ctrl+却把python进程也给发了个挂起的信号呢?
在bash里面,./mysh.sh这条命令运行时,当前shell fork了一个子shell,当全部命令退出后,就kill掉这个子shell
tail还在运行时
```
PID STAT COMMAND
83540 S+ Python mypy.py
83539 S+ sh ./mysh.sh
```
tail被Ctrl-C掉了时
```
PID STAT COMMAND
83540 S Python mypy.py
```
再额外实验一下 如果用source mysh.sh,也就是在当前shell环境中运行命令
那么会得到
```
PID STAT COMMAND
83766 SN Python mypy.py
```
Ctrl-Z或Ctrl-C都不影响python进程
再进一步实验,我在mysh.sh里面加了一句
```
nohup python mypy.py &
tail -f nohup.out
ping 114.114.114.114
```
Ctrl+C并不会开始ping,而是与前一次一样,退出了当前的shell
当我kill掉tail的进程,终端里开始输出ping的结果
所以实际上接收Ctrl+C和Ctrl+Z的都是“sh ./mysh.sh”
我理解python进程也是“sh ./mysh.sh”的子进程吧
谢谢回复。
但是还是没有回应,为何mysh.sh收到了ctrl+C和ctrl+Z会有不同的结果。
【 在 Austinpb 的大作中提到: 】
: [md]
: > 有一个脚本mypy.py,里面就是print和Sleep循环
: > 还有一个脚本 mysh.sh 里面就是
: ...................
ctrl-z产生的是SIGTSTP
【 在 nitroethane 的大作中提到: 】
: (自我感觉好像描述的没问题,有问题请指出)
: 在支持 job control 的 shell 中,shell 的子进程组成的进程组分为两种,前台进程组和后台进程组。
: ctrl-z 产生 sighup 信号,ctrl-c 产生 sigint 信号,当在shell里按下这两个键的时候信号会发送到前台进程组中。
: ...................
一句话来说是:为什么nohup的python进程被ctrl+z控制,但是无视了ctrl+c
经过实验:nohup的进程是无视SIGINT(ctrl+c)的,但响应SIGSTOP(ctrl+z)
正如@nitroethane 所说:当在shell里按下这两个键的时候信号会发送到前台进程组中。
所以前台进程组的其他几个进程都被kill了,但是python进程没有。
在kill掉其他前台进程以后,对python进程做一下发送不同信号的测试。
```
$ ps aux | grep mypy | grep -v grep
PID STAT COMMAND
65939 S Python mypy.py
```
```
$ kill -s SIGHUP 65939
$ ps aux | grep mypy | grep -v grep
PID STAT COMMAND
65939 S Python mypy.py
```
```
$ kill -s SIGINT 65939
$ ps aux | grep mypy | grep -v grep
PID STAT COMMAND
65939 S Python mypy.py
```
```
$ kill -s SIGSTOP 65939
$ ps aux | grep mypy | grep -v grep
PID STAT COMMAND
65939 T Python mypy.py
```
```
$ kill -s SIGKILL 65939
$ ps aux | grep mypy | grep -v grep
PID STAT COMMAND
```
前面4楼那篇我说的不对,下面是我走的弯路,留下可供参考,感谢LZ,学习了。
参考了这篇:[译] 如何杀死一个进程和它的所有子进程
pstree来看一下这几条命令的关系
```
| | \-+= 62423 austin sh ./mypy.sh
| | |--- 62424 austin /Library/Frameworks/Python.framework/Versions/3.8/Resources/Python.app/Contents/MacOS/Python mypy.py
| | \--- 62425 austin tail -f nohup.out
```
我试了一下kill掉pid 62423这个sh进程,留下了62424(python)和62425(tail)这两个孤儿
```
|--- 62424 austin /Library/Frameworks/Python.framework/Versions/3.8/Resources/Python.app/Contents/MacOS/Python mypy.py
\--- 62425 austin tail -f nohup.out
```
【 在 zithersw 的大作中提到: 】
: 谢谢回复。
: 但是还是没有回应,为何mysh.sh收到了ctrl+C和ctrl+Z会有不同的结果。
: