Chinaunix
标题:
这个都不清楚就别说会用linux
[打印本页]
作者:
wslmyb
时间:
2010-09-10 12:36
标题:
这个都不清楚就别说会用linux
转到这个
http://linux.chinaunix.net/bbs/thread-1170850-1-1.html
作者:
l.darkfire
时间:
2010-09-10 14:01
"说到底最不明白的是2点
1 source是否新开了一个进程。
没开的说法:看现象1中的102部分
开了的说法:看现象1中的104部分
也许这个问题应该结合是否为前台后台等综合讨论。
2 所谓的&是否受终端的影响?终端一旦关闭则&的都将关闭(我做的实验都是这样,除非特殊的脚本能做成守护进程的方式)。主要现在网络上的帖子都是讲的fg,bg,jobs怎么用
,没有考虑到终端问题。"
1. source不开新进程,仅仅是在当前bash环境中执行另外一段bash代码,代码中的变量操作等对本环境有效。等同于.命令。
2. 本质上来说,以command &以后,这个进程就不在前台受控制了,比如你没法对它进行输入。终端关闭之所以导致&进程退出,是因为终端会在关闭时向进程发一个SIGHUP信号,进程对这个信号的默认处理方式是退出。应该也可以将终端设置成在关闭时不向进程发送SIGHUP信号,这样那些&进程就不会退出了。我的SecureCRT就不会有这种情况。
作者:
wslmyb
时间:
2010-09-10 14:17
回复l.darkfire:
谢谢回答。不过对于你说的有一些问题。
“1. source不开新进程,仅仅是在当前bash环境中执行另外一段bash代码,”
请参看现象2中的sleep 104部分。
root 6209 1 0 11:01 ? 00:00:00 gnome-terminal //图形界面,父进程为1,没有问题
root 6290 6209 0 11:02 pts/4 00:00:00 bash //本身的pts/4,父进程为图形界面,没有问题
root 6388 6290 0 11:02 pts/4 00:00:00 bash //运行sleep 104命令的shell,父进程为6290
root 6426 6388 0 11:04 pts/4 00:00:00 sleep 104 //sleep 104命令,父进程shell为6388
按你的意思,6426(sleep 104命令)的父进程应该为pts/4,也就是6290.
可现在的情况是sleep命令它的父进程为6388.也就是pts/4(6290)又开了一个shell来执行sleep.
作者:
l.darkfire
时间:
2010-09-10 14:21
root 6388 6290 0 11:02 pts/4 00:00:00 bash //运行sleep 104命令的shell,父进程为6290
这个是怎么来的
作者:
wslmyb
时间:
2010-09-10 14:24
我就是不清楚这个是怎么来的 -_-!
作者:
l.darkfire
时间:
2010-09-10 14:30
6290一定以某种方式fork了6388,比如( ... ),这个表达式会fork一个新的子bash,然后在子bash里执行括号里的命令,比如以下代码就可以产生上述情况:
#!/bin/bash
( sleep 104 )
作者:
wslmyb
时间:
2010-09-10 14:35
回复l.darkfire:
对于你说的&后台的问题,我重新编辑了一下帖子。你能再帮我解释一下这个现象么,谢谢!
后台&问题:
现有脚本first.sh和second.sh
[root@localhost /]# cat /abc/first.sh
#!/bin/bash
. /abc/second.sh &
[root@localhost /]# cat /abc/second.sh
#!/bin/bash
while true
do
sleep 500
done
现在执行
[root@localhost /]# source /abc/first.sh &
[1] 10458
[root@localhost /]# jobs
[1]+ Done source /abc/first.sh
[root@localhost /]#
ps auxf回车:
root 10386 0.0 1.6 81644 17388 ? Sl 14:24 0:00 gnome-terminal
root 10391 0.0 0.0 2480 656 ? S 14:24 0:00 \_ gnome-pty-h
root 10392 0.0 0.1 4912 1556 pts/1 Ss 14:24 0:00 \_ bash
root 10461 0.0 0.0 4608 920 pts/1 R+ 14:27 0:00 \_ ps auxf
root 10390 0.0 0.0 12304 952 ? S 14:24 0:00 scim-bridge
root 10459 0.0 0.0 4912 696 pts/1 S 14:27 0:00 bash
root 10460 0.0 0.0 3956 472 pts/1 S 14:27 0:00 \_ sleep 500
发现10459这个bash的父进程已经是根了。
然后退出这个终端,重新开一个终端
ps auxf回车:
root 10459 0.0 0.0 4912 696 ? S 14:27 0:00 bash
root 10460 0.0 0.0 3956 472 ? S 14:27 0:00 \_ sleep 500
root 10492 3.2 1.6 81528 17256 ? Sl 14:28 0:00 gnome-terminal
root 10496 0.0 0.0 2480 656 ? S 14:28 0:00 \_ gnome-pty-h
root 10497 0.3 0.1 4912 1496 pts/2 Ss 14:28 0:00 \_ bash
root 10518 0.0 0.0 4608 920 pts/2 R+ 14:28 0:00 \_ ps auxf
root 10495 0.0 0.0 12304 952 ? S 14:28 0:00 scim-bridge
发现10459这个进程还在。
有的人说&放在后台会受终端的影响,可是现在这个10459和10460进程都在,怎么解释?
作者:
wslmyb
时间:
2010-09-10 14:38
回复6楼的说法:
对于这种说法,是不是我可以这样理解:当source command &。有后台&出现的情况,source也会出现fork的情况?
作者:
l.darkfire
时间:
2010-09-10 14:38
在是正常的,说明你的终端在断开时没有发SIGHUP信号给进程。
说白了这是终端的特性,它在断开时,可以发SIGHUP信号也可以不发SIGHUP信号。和进程本身没有
什么关系。
作者:
l.darkfire
时间:
2010-09-10 14:57
“对于这种说法,是不是我可以这样理解:当source command &。有后台&出现的情况,source也会出现fork的情况?”
首先source后面通常是跟一个脚本名,在当前环境下去执行脚本中的内容。
但是对于source script.sh &这种情况,bash会fork一个子进程去执行script,这是加了&后的不同之处。我也是刚才实验了一下才知道。
作者:
wslmyb
时间:
2010-09-10 14:58
回复9楼:
那请看我后来补充的这个例子(first,second)。
这个终端如果在断开时,没有发SIGHUP信号。现在的现象是,10459的父进程为什么是1.这个进程10459是怎么来的?
[root@localhost /]# source /abc/first.sh &
[1] 10458
[root@localhost /]# jobs
[1]+ Done source /abc/first.sh
source first.sh进程是10458,就1句话,放在后台执行second.sh。所以马上jobs,看到已经Done。应该可以确定10459的父进程是10458.而10458是first而并非是本身的pts/1这个Shell(10392)。
之间的关系可以认为是这样
init->terminial->10392(pts/1)->10458(first)->10459(second)->10460(sleep)
因为10458瞬间执行完。而现在我不论是否退出终端,ps auxf和ps -ef看到10459的父进程都变为1了。这是怎么解释?为什么10459的父进程会变为1?
作者:
l.darkfire
时间:
2010-09-10 15:04
因为当一个进程(10459)的父进程(1045
死亡时,它的父进程就自动被系统设置为init(1)。
具体在父进程死亡的时候,把它的所有子进程的父进程设置为init(1)。
作者:
l.darkfire
时间:
2010-09-10 15:04
因为当一个进程(10459)的父进程(10458 )死亡时,它的父进程就自动被系统设置为init(1)。
具体是在父进程死亡的时候,就把它的所有子进程的父进程设置为init(1)。
作者:
wslmyb
时间:
2010-09-10 15:06
可是在没有退出终端的时候,10459的父进程应该是10392啊.因为没有退出终端呢。刚执行完source first & 后执行ps看结果,看到的10459的父进程也为1了。
而且现在这些都是用source执行的,居然都是父子进程的关系,就是你刚才说的source script &的方式会fork一个shell。所以我最开始对这事很不明白。
作者:
l.darkfire
时间:
2010-09-10 15:09
1. source script不会fork子bash来执行。
2. source script &会fork子bash来执行。
3. 父进程A死亡后,它的子进程B的父进程全被设置为1,而不是被设置为父进程A的父进程C。
作者:
wslmyb
时间:
2010-09-10 15:14
哦,好的。非常感谢!
作者:
wslmyb
时间:
2010-09-10 15:15
CU的高手就是多啊,这个事纠结了我1天了。
作者:
l.darkfire
时间:
2010-09-10 15:16
互相学习呗
作者:
wslmyb
时间:
2010-09-10 15:24
还有1个问题。
init->terminial->10392(pts/1)->10458(first)->10459(second)->10460(sleep)
在10458瞬间执行完退出的时候,为什么没有给10459发SIGHUP信号呢。如果发了,10459就应该结束的。
作者:
l.darkfire
时间:
2010-09-10 15:27
自己死亡便向子进程发送SIGHUP的特性是终端才有的,程序自己默认并不会做这个事情,除非你自己编写一个程序这样做。
作者:
wslmyb
时间:
2010-09-10 15:31
哦,原来是这样!l.darkfire兄你太N了。
作者:
l.darkfire
时间:
2010-09-10 15:47
N的都躲在旁边看呢
作者:
chinesedragon
时间:
2010-09-13 11:52
看看!!!!!!
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2