一. 现象
while中cd在退出while后失效,for & if & case中cd在退出块后生效。
1. while中cd在退出while后失效
$ echo line_1 > ~/1
$ echo line_2 >> ~/1
$ pwd;cat ~/1 | while read l;do echo $l;cd /folder2;pwd;done;pwd
/folder1
line_1
/folder2
line_2
/folder2
/folder1
2. for中cd在退出for后仍有效
$ pwd;for l in `cat ~/1`;do echo $l;cd /folder2;pwd;done;pwd
/folder1
line_1
/folder2
line_2
/folder2
/folder2
3. if中cd在退出if后仍有效
$ pwd;if [ "1" == "1" ] ; then cd /folder2;pwd;fi;pwd
/folder1
/folder2
/folder2
4. case中cd在退出case后仍有效
$ pwd;i="1";case $i in 1)cd /folder2;pwd; ;; esac;pwd
/folder1
/folder2
/folder2
二. while & for & if & case块内并没有开新进程
猜测原因,难道while中开了子进程, 而for & if & case 中没有开子进程,所以while中cd无效、for & if & case中cd有效?
来测试一下。
变量"$$"就是当前进程号。
1. while里进程号不变
$ pwd;echo "current pid : $$";cat ~/1 | while read l;do echo $l;cd /folder2;pwd;echo "current pid : $$";done;pwd;echo "current pid : $$";
/folder1
current pid : 20007
line_1
/folder2
current pid : 20007
line_2
/folder2
current pid : 20007
/folder1
current pid : 20007
2. for里进程号不变
$ pwd;echo "current pid : $$";for l in `cat ~/1`;do echo $l;cd /folder2;pwd;echo "current pid : $$";done;pwd;echo "current pid : $$";
/folder1
current pid : 20007
line_1
/folder2
current pid : 20007
line_2
/folder2
current pid : 20007
/folder2
current pid : 20007
3. if里进程号不变
$ pwd;echo "current pid : $$";if [ "1" == "1" ] ; then cd /folder2;pwd;echo "current pid : $$";fi;pwd;echo "current pid : $$";
/folder1
current pid : 20007
/folder2
current pid : 20007
/folder2
current pid : 20007
4. case里进程号不变
$ pwd;echo "current pid : $$";i="1";case $i in 1)cd /folder2;pwd;echo "current pid : $$"; ;; esac;pwd;echo "current pid : $$";
/folder1
current pid : 20007
/folder2
current pid : 20007
/folder2
current pid : 20007
进程号没有变。那有没有开线程?
(虽然linux中线程和进程没有区别。。。)
ps -ef|grep -e PID -e $$
可以查看父子进程情况。
这个命令可以过滤查看当前进程(进程号$$)的关联父子进程.PID一列是子进程号,PPID是父进程号。
三. while内开了bash子线程,for & if & case内不会开bash子线程。
1. whlie里多了个bash的子线程
$ pwd;echo "current pid : $$";ps -ef|grep -e PID -e $$;cat ~/1 | while read l;do echo $l;cd /folder2;pwd;echo "current pid : $$";ps -ef|grep -e PID -e $$;done;pwd;echo "current pid : $$";ps -ef|grep -e PID -e $$;
/folder1
current pid : 20007
UID PID PPID C STIME TTY TIME CMD
peggy 19230 20007 0 11:27 pts/20 00:00:00 ps -ef
peggy 20007 20006 0 9月08 pts/20 00:00:00 -bash
line_1
/folder2
current pid : 20007
UID PID PPID C STIME TTY TIME CMD
peggy 19233 20007 0 11:27 pts/20 00:00:00 -bash
peggy 20007 20006 0 9月08 pts/20 00:00:00 -bash
line_2
/folder2
current pid : 20007
UID PID PPID C STIME TTY TIME CMD
peggy 19233 20007 0 11:27 pts/20 00:00:00 -bash
peggy 20007 20006 0 9月08 pts/20 00:00:00 -bash
/folder1
current pid : 20007
UID PID PPID C STIME TTY TIME CMD
peggy 19238 20007 0 11:27 pts/20 00:00:00 ps -ef
peggy 20007 20006 0 9月08 pts/20 00:00:00 -bash
其中
peggy 19233 20007 0 11:27 pts/20 00:00:00 -bash
表明
while里多个bash子线程。
ps -ef 子线程可以忽略。
2. wilie里没有新开bash子线程
$ pwd;echo "current pid : $$";ps -ef|grep -e PID -e $$;for l in `cat ~/1`;do echo $l;cd /folder2;pwd;echo "current pid : $$";ps -ef|grep -e PID -e $$;done;pwd;echo "current pid : $$";ps -ef|grep -e PID -e $$;
/folder1
current pid : 20007
UID PID PPID C STIME TTY TIME CMD
peggy 19314 20007 0 11:28 pts/20 00:00:00 ps -ef
peggy 20007 20006 0 9月08 pts/20 00:00:00 -bash
line_1
/folder2
current pid : 20007
UID PID PPID C STIME TTY TIME CMD
peggy 19317 20007 0 11:28 pts/20 00:00:00 ps -ef
peggy 20007 20006 0 9月08 pts/20 00:00:00 -bash
line_2
/folder2
current pid : 20007
UID PID PPID C STIME TTY TIME CMD
peggy 19319 20007 0 11:28 pts/20 00:00:00 ps -ef
peggy 20007 20006 0 9月08 pts/20 00:00:00 -bash
/folder2
current pid : 20007
UID PID PPID C STIME TTY TIME CMD
peggy 19321 20007 0 11:28 pts/20 00:00:00 ps -ef
peggy 20007 20006 0 9月08 pts/20 00:00:00 -bash
3. wilie里没有新开bash子线程
$ pwd;echo "current pid : $$";ps -ef|grep -e PID -e $$;if [ "1" == "1" ] ; then cd /folder2;pwd;echo "current pid : $$";fi;pwd;ps -ef|grep -e PID -e $$;echo "current pid : $$";ps -ef|grep -e PID -e $$;
/folder2
current pid : 20007
UID PID PPID C STIME TTY TIME CMD
peggy 19774 20007 0 11:35 pts/20 00:00:00 ps -ef
peggy 20007 20006 0 9月08 pts/20 00:00:00 -bash
/folder2
current pid : 20007
/folder2
UID PID PPID C STIME TTY TIME CMD
peggy 19776 20007 0 11:35 pts/20 00:00:00 ps -ef
peggy 20007 20006 0 9月08 pts/20 00:00:00 -bash
current pid : 20007
UID PID PPID C STIME TTY TIME CMD
peggy 19778 20007 0 11:35 pts/20 00:00:00 ps -ef
peggy 20007 20006 0 9月08 pts/20 00:00:00 -bash
4. wilie里没有新开bash子线程
$ pwd;echo "current pid : $$";ps -ef|grep -e PID -e $$;i="1";case $i in 1)cd /folder2;pwd;echo "current pid : $$";ps -ef|grep -e PID -e $$; ;; esac;pwd;echo "current pid : $$";ps -ef|grep -e PID -e $$;
/folder2
current pid : 20007
UID PID PPID C STIME TTY TIME CMD
peggy 19857 20007 0 11:36 pts/20 00:00:00 ps -ef
peggy 20007 20006 0 9月08 pts/20 00:00:00 -bash
/folder2
current pid : 20007
UID PID PPID C STIME TTY TIME CMD
peggy 19859 20007 0 11:36 pts/20 00:00:00 ps -ef
peggy 20007 20006 0 9月08 pts/20 00:00:00 -bash
/folder2
current pid : 20007
UID PID PPID C STIME TTY TIME CMD
peggy 19861 20007 0 11:36 pts/20 00:00:00 ps -ef
peggy 20007 20006 0 9月08 pts/20 00:00:00 -bash
四. 结论
- while中执行cd命令,在退出while后失效,因为会开一个bash子线程来执行while,子线程内(或者子进程内)的cd不会影响到当前进程。
- for & if & case中执行cd命令,在退出while后仍生效,因为不会开一个bash子线程来执行for & if & cae,所以while & if & case块内cd命令会影响到你进程。