Linux中国 Linux中国门户站!
设为主页 设为主页
收藏本站 收藏本站
 
当前位置 :首页 ->Linux技术 ->Linux程序设计 ->正文

Linux 操作系统编程之Shell 问答录

来源: 作者: 时间:2007-04-11 点击: [收藏] [投稿]

前些天在CU上讨论一个统计正在执行的脚本数量的问题过程中,发现自己对于shell怎么样执行命令方面了解还是甚少,惭愧惭愧...期间得到waker兄的指点,在此表示感谢!他的说法除了个别地方不太准确外,基本上是正确的。这些天抽时间找了些资料研究了一下,又学到了不少!这里把我的一点心得以问答的形式贴出来,供大家参考。小弟才疏学浅,错误的地方一定很多,欢迎大家拍砖、指正!

Q1: shell怎么样执行“简单”命令?

A: 这里的简单命令和bash参考手册里的含义相同,形式上一般是:命令的名称加上它的参数。有三种不同的简单命令:

1.内置命令(builtin)

是shell解释程序内建的,有shell直接执行,不需要派生新的进程。有一些内部命令可以用来改变当前的shell环境,如:

cd /path
var=value
read var
export var
...

2.外部命令("external command" 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的环境。

Q2: shell脚本是否作为单独的一个进程执行?

A: 不是,shell脚本本身不能作为一个进程。如上面讲的,shell脚本由一个shell解释程序来解释、运行其中的命令。这个shell解释程序是单独的一个进程,脚本中的外部命令也都作为独立进程依次被运行。这也就是为什么ps不能找到正在运行的脚本的名字的原因了。作为一个替代方案,你可以这样调用脚本:

sh script-name

这时shell解释程序“sh”作为一个外部命令被显式地调用,而script-name作为该命令的命令行参数可以被我们ps到。

另外,如果你的系统上有pidof命令可用,它倒是可以找出shell脚本进程(实际上应该是执行shell脚本的子shell进程)的进程ID:

pidof -x script-name

Q3: shell何时在子shell中执行命令?

A: 在此我们主要讨论Bourne shell及其兼容shell。在许多情况下shell会在子shell中执行命令:

1.(...)结构

小括号内的命令会在一个子shell环境中执行,命令执行的结果不会影响当前的shell环境。需要注意是此时变量$$会显示当前shell的进程id,而不是子shell的进程id。

参考:{...;}结构中的命令在当前shell中执行,(内部)命令执行的结果会影响当前的shell环境。

2.后台执行或异步执行

command&命令由一个子shell在后台执行,当前shell立即取得控制等候用户输入。后台命令和当前shell的执行是并行的,但没有互相的依赖、等待关系,所以是异步的并行。

3.命令替换

command`(Bourn shell及兼容shell/csh),$(command)(在ksh/bash/zsh中可用)把command命令执行的标准输出代换到当前的命令行。command在子shell环境中执行,结果不会影响当前的shell环境。

4.管道(不同的shell处理不同)

cmd1和cmd2并行执行,并且相互有依赖关系,cmd2的标准输入来自cmd1的标准输出,二者是“同步”的。对管道的处理不同的shell实现的方式不同。在linux环境下大多数shell(bash/pdksh/ash/dash等,除了zshell例外)都把管道中所有的命令在子shell环境中执行,命令执行的结果不会影响当前的shell环境。

Korn shell的较新的版本(ksh93以后)比较特殊,管道最后一级的命令是在当前shell执行的。这是一个feature而非BUG,在POSIX标准中也是允许的。这样就使下面的命令结构成为可能:



 如果您对本文有任何疑问或者建议,请到讨论区发表您的意见: >> 论坛入口 <<



上一篇:Linux编程之:五个常见PHP数据库问题   下一篇:Linux脚本开发数学库在PHP中的重要性

文章评论】 【收藏本文】 【推荐好友】 【打印本文】 【我要投稿】 【论坛讨论
更多相关文章