知识屋:更实用的电脑技术知识网站
所在位置:首页 > 操作系统 > linux

linux shell脚本文件执行分析

发布时间:2014-09-05 15:50:23作者:知识屋


linux shell脚本文件执行分析
 
一.shell脚本父子进程分析
 
代码:
[cpp] 
#!/bin/bash  
echo $$  
ps -ef |grep `echo $$`  
echo "-------------------------------------"  
( pwd;echo $$;ps -ef |grep `echo $$`;)  
echo "-------------------------------------"  
{ pwd;echo $$;ps -ef |grep `echo $$`; }  
运行结果1:  www.zhishiwu.com  

 
结果分析1:
1.      最后一行显示当前登录shell进程ID为9561;
2.      第三行显示登录shell派生出一个进程ID为10767的shell执行进程;该进程负责扫描shell脚本进行执行;
3.      10767脚本执行进程负责逐行执行脚本:遇到内置命令直接在当10767进程中执行,遇到可执行程序就fork 新的子进进程来执行。
4.      进程号为 10768和10769的进程都是执行shell 10767进程派生的子进程ps 和grep .
5.      10767脚本执行进程扫描到( com1;com2;) 语句群时,会再派生一个ID为10771子shell负责执行()内的命令和语句:10771 逐行扫描()中的语句,按照步骤3的规则进行处理:进程号 10773 grep 还有另一个进程 ps 都是10771又派生出的子进程,ps子进程的父进程是10771 此处没有显示出来。
6.      10767脚本执行进程扫描到{ com1;com2;} 语句时,不会新派生子shell,直接使用当前进程10767进行负责逐行执行脚本。
 
运行结果2:


 
结果分析2
其运行结果和运行1是一样的,bash  cpro.sh 和直接运行cpro.sh 的工作机制是一样的,都会派生出一个执行shell,逐行读脚本进行执行;
   www.zhishiwu.com  
总结:
Ø  在当前shell中执行内部命令不会派生子shell,因此有些内部命令才能够改变当前的shell执行环境;
Ø  在当前shell中执行外部命令或脚本时会派生子shell,所以这时命令的执行不会影响当前shell环境;
Ø  要想在当前shell中执行脚本,而不派生子shell,可以使用 . 和source 命令 + 脚本名进行执行
Ø  ./command.sh = bash ./command.sh 当前shell会派生子shell执行脚本文件,脚本的执行不会影响到当前shell环境
Ø  . ./command.sh = source ./command.sh 直接在当前shell中执行脚本,脚本的执行回影响到当前shell环境
 
二.管道与shell脚本执行关系 command | read var 和 comand | while read var
代码:
[cpp] 
pwd | read var  
echo $var  #1  
 www.zhishiwu.com  
ls -l |while read var  
do  
echo $var #2  
done  
结果分析:
#1 输出时空置
#2输出有值
这就是管道的秘笈,bash 在执行pwd | read var时管道两边的都是子shell执行,执行echo $var 是父shell执行,父shell无法读到子shell变量
bash 执行ls -l |while read var 左边是子shell 右边是父shell执行,故最后可以读到内容
shell脚本执行汇总:
 
1.内置命令(builtin)
是shell解释程序内建的,由shell直接执行,不需要派生新的进程;有一些内部命令可以用来改变当前的shell环境,如:
cd /path
var=value
read var
export var
...
  www.zhishiwu.com  
2.外部命令("externalcommand" or "disk command")
二进制可执行文件,需要由磁盘装入内存执行。会派生新的进程,shell解释程序会调用fork自身的一个拷贝,然后用exec系列函数来执行外部命令,然后外部命令就取代了先前fork的子shell。
 
3.shell脚本(script)
shell解释程序会fork+exec执行这个脚本命令,在exec调用中内核会检查脚本的第一行(如:#!/bin/sh),找到用来执行脚本的解释程序,然后装入这个解释程序,由它解释执行脚本程序。解释程序可能有很多种,各种shell(Bourne shell,Korn shell cshell,rc及其变体ash,dash,bash,zshell,pdksh,tcsh,es...),awk,tcl/tk,expect,perl,python,等等。在此解释程序显然是当前shell的子进程。如果这个解释程序与当前使用的shell是同一种shell,比如都是bash,那么它就是当前shell的子shell,脚本中的命令都是在子shell环境中执行的,不会影响当前shell的环境。
   www.zhishiwu.com  
三. 如何查看一个命令时内建命令还是外部命令(程序)
用户输入命令之后,shell一般fork,在子shell中执行命令。内建命令不是这样的。 执行内建命令相当于调用Shell进程中的一个函数,并不创建新的进程。
如何查看命令是否为内建命令?
 
type命令
   type - write a description of command type
 
·        不加参数,会显示命令是内建命令还是外部命令。
[cpp] 
$type echo  
echoisa shell builtin  
  
·         -t 参数,返回值  
      file    :表示为外部指令,一般是外部可执行程序,ELF格式   
      alias   :表示该指令为命令别名所设定的名称;  
      builtin :表示该指令为 bash 内建的指令功能;  
$type-t ls  
 alias  
$type-t alias  
builtin  
$type-t chmod  
file    www.zhishiwu.com  
·        -a 会将命令PATH 路径显示出来。  
 
其他相关命令:
which命令 只能找到path 下可执行程序,即外部程序,内建命令没有办法识别
 
file 命令查看文件类型,file 会尝试读文件头,解析文件类型 
 
http://blog.csdn.net/hittata/article/details/8017368
 
(免责声明:文章内容如涉及作品内容、版权和其它问题,请及时与我们联系,我们将在第一时间删除内容,文章内容仅供参考)
收藏
  • 人气文章
  • 最新文章
  • 下载排行榜
  • 热门排行榜