注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

itoedr的it学苑

记录从IT文盲学到专家的历程

 
 
 

日志

 
 

bash shell 中的次级脚本命令执行容器:exec、source、sh、run-parts的区别  

2013-12-23 21:37:14|  分类: linux工具命令 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

       fork出来的子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。特别需要注意的是,子进程持有的是上述存储空间的“副本”,这意味着父子进程间不共享这些存储空间。

      UNIX将复制父进程的地址空间内容给子进程,因此,子进程有了独立的地址空间。在不同的UNIX (类unix)系统下,我们无法确定fork之后是子进程先运行还是父进程先运行,这依赖于系统的实现。


       bash是linux/unix下一个超级系统,实际工作中也是越来越多的人开始使用。其中三个次级脚本命令执行容器大有用处,因为需要做一些工作,笔者从网络世界找来一些资料对三者进行了简单比较。

      1)sh:父进程会fork一个子进程,shell script在子进程中执行;
     2)source:在原进程中执行,不会fork子进程;
     3)exec:在原进程中执行,但是同时会终止原进程;
     4)run-parts:执行一个目录中全部可执行文件
          centos中,run-parts命令位于/usr/bin/run-parts,而在ubuntu下,run-parts 位于 /bin/run-parts。
          run-parts的内容是很简单的一个可执行shell脚本,就是遍历目标文件夹,执行第一层目录下的可执行权限的文件。
 
      注:使用export会把父进程中的变量向子进程中继承,但是反过来却不行,在子进程中,不管环境如果改变,均不会影响父进程。

       使用案例:


   ###  1.sh (bash脚本1.sh)
  1. #!/bin/bash  
  2. A=B  
  3. echo "PID for 1.sh before exec/source/fork:$"  
  4. export A  
  5. echo "1.sh: \$A is $A"  
  6. case $1 in  
  7.         exec)  
  8.                 echo "using exec..."  
  9.                 exec ./2.sh ;;  
  10.         source)  
  11.                 echo "using source..."  
  12.                 . ./2.sh ;;  
  13.         *)  
  14.                 echo "using fork by default..."  
  15.                 ./2.sh ;;  
  16. esac  
  17. echo "PID for 1.sh after exec/source/fork:$"  
  18. echo "1.sh: \$A is $A" 


  ###2.sh  (bash脚本2.sh)

  1. #!/bin/bash  
  2. echo "PID for 2.sh: $"  
  3. echo "2.sh get \$A=$A from 1.sh"  
  4. A=C  
  5. export A  
  6. echo "2.sh: \$A is $A" 


『在命令行中去执行情况记录』

./1.sh fork

bash shell 中的次级脚本命令执行容器:exec、source以及sh的区别 - itoedr - itoedr的it学苑
 

      可以看到,1.sh是在父进程中执行,2.sh是在子进程中执行的,父进程的PID是5344,而子进程的是5345,当子进程执行完毕后,控制权返回到父进程。同时,在子进程改变环境变量A的值不会影响到父进程。


./1.sh source

bash shell 中的次级脚本命令执行容器:exec、source以及sh的区别 - itoedr - itoedr的it学苑
 

     由结果可知,1.sh和2.sh都是在同一进程中执行的,PID为5367


./1.sh exec

bash shell 中的次级脚本命令执行容器:exec、source以及sh的区别 - itoedr - itoedr的it学苑
 

可知,两个脚本都是在同一进程中执行,但是请注意,使用exec终止了原来的父进程,因此,可以看到


  1. echo "PID for 1.sh after exec/source/fork:$"  
  2. echo "1.sh: \$A is $A"  
这两个命令没有执行。

附1:fork的解注
          fork是linux环境下的子进程创建工具。

     由fork创建的新进程被称为子进程(childprocess).该函数被调用一次,但返回两次.两次返回的区别是子进程的返回值是0,而父进程的返回值则是新子进程的进程id.

     将子进程id返回给父进程的理由是:因为一个进程的子进程可以多于一个,所以没有一个函数使一个进程可以获得其所有子进程的进程id.

     fork使子进程得到返回值0的理由是:一个进程只会有一个父进程,所以子进程总是可以调用getppid以获得其父进程的进程id(进程id0总是由交换进程使用,所以一个子进程的进程id不可能为0).

     子进程和父进程共享很多资源,除了打开文件之外,很多父进程的其他性质也由子进程继承:

.实际用户id

.实际组id

.有效用户id

.有效组id?

.添加组id.

.进程组id.

.对话期id.

.控制终端.

.设置-用户-id标志和设置--id标志.

.当前工作目录.

.根目录.

.文件方式创建屏蔽字.

.信号屏蔽和排列.

.对任一打开文件描述符的在执行时关闭标志.

.环境.

.连接的共享存储段.

.资源限制.

 

父.子进程之间的区别是:

.fork的返回值.

.进程id.

.不同的父进程id.

.子进程的tms_utime,tms_stime,tms_cutime以及tms_ustime设置为0.

.父进程设置的锁,子进程不继承.

.子进程的未决告警被清除.

.子进程的未决信号集设置为空集.


   使fork失败的两个主要原因是:(a)系统中已经有了太多的进程(通常意味着某个方面出了问题),或者(b)该实际用户id的进程总数超过了系统限制?

    其中child_max规定了每个实际用户id在任一时刻可具有的最大进程数.更多内容需进一步阐述.

fork有两种用法:

(1)一个父进程希望复制自己,使父.子进程同时执行不同的代码段.这在网络服务进程中是常见的——父进程等待委托者的服务请求.当这种请求到达时,父进程调用fork,使子进程处理此请求.父进程则继续等待下一个服务请求.

(2)一个进程要执行一个不同的程序?

   这对shell是常见的情况.在这种情况下,子进程在从fork返回后立即调用exec.


附2:source、sh、bash、./执行脚本的区别


1、source命令用法:

  source FileName

  作用:在当前bash环境下读取并执行FileName中的命令。该filename文件可以无"执行权限"

    注:该命令通常也可用命令“.”来替代。

    如:source .bash_profile

        . .bash_profile两者等效。

    source(或点)命令通常用于重新执行刚修改的初始化文档。

    source命令(从 C Shell 而来)是bash shell的内置命令。

    点命令,就是个点符号,(从Bourne Shell而来)。

        说明:run-parts后面是一个文件夹名称。

 

2、sh和bash命令用法:

     sh FileName

     bash FileName

     作用:在当前bash环境下读取并执行FileName中的命令。该filename文件可以无"执行权限"

     注:两者在执行文件时的不同,是分别用自己的shell来跑文件。

 

   sh使用“-n”选项进行shell脚本的语法检查,使用“-x”选项实现shell脚本逐条语句的跟踪,

   可以巧妙地利用shell的内置变量增强“-x”选项的输出信息等。

 

3、./的命令用法:

     ./FileName

     作用:打开一个子shell来读取并执行FileName中命令。

 

     注:运行一个shell脚本时会启动另一个命令解释器.

         每个shell脚本有效地运行在父shell(父 shell)的一个子进程里.

          这个父shell是指在一个控制终端或在一个xterm窗口中给你命令指示符的进程.

         shell脚本也可以启动他自已的子进程.

         这些子shell(即子进程)使脚本并行地,有效率地地同时运行脚本内的多个子任务.


 ***************************************************

shell的嵌入命令:

: 空,永远返回为true
.   从当前shell中执行操作
break 退出for、while、until或case语句
cd 改变到当前目录
continue 执行循环的下一步
echo 反馈信息到标准输出
eval 读取参数,执行结果命令
exec 执行命令,但不在当前shell
exit 退出当前shell
export 导出变量,使当前shell可利用它
pwd 显示当前目录
read 从标准输入读取一行文本
readonly 使变量只读
return 退出函数并带有返回值
set 控制各种参数到标准输出的显示
shift 命令行参数向左偏移一个
test 评估条件表达式
times 显示shell运行过程的用户和系统时间
trap 当捕获信号时运行指定命令
ulimit 显示或设置shell资源
umask 显示或设置缺省文件创建模式
unset 从shell内存中删除变量或函数
wait 等待直到子进程运行完毕

  评论这张
 
阅读(211)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017