8.2.4 编写一个简单的shell脚本
shell脚本是包含shell可执行命令的文件。shell脚本中的命令可以是用户在shell提示符后面输入的任何命令。比如,shell脚本中的某条命令可以运行某个Linux实用程序、编译过的程序或者是另一个shell脚本。与用户在命令行下输入的命令一样,shell脚本中的命令可以引用任意文件,并可以有自己的输入和输出,这些输入和输出可能从某个文件重定向而来或定向到某个文件,又或者是通过管道发送。脚本本身的输入和输出也可以使用管道和重定向技术。
除了可以使用用户在命令行下面输入的命令之外,shell脚本还可以使用控制流命令(也称为控制结构)。使用这组命令可以改变脚本中命令的执行顺序,就像使用结构化程序编程语言改变语句的执行顺序一样。查阅第11.1节和第9.7节可以知道更多细节。
shell一条接着一条地解释并执行shell脚本中的命令。这样使用shell脚本就可以简单快速地启动一个复杂的任务序列或者是一个重复性的过程。
1. chmod:使文件可执行
要想用shell脚本的文件名作为命令执行该脚本,用户必须具有该脚本的文件读权限和执行权限(参见第4.4节)。读权限使用户可以读取包含脚本的文件。而执行权限告诉shell和系统,该文件的所有者、组用户或者其他用户可以执行这个文件,它暗示这个文件的内容是可以执行的。
当使用编辑器创建shell脚本的时候,该文件通常并没有设置执行权限。下面的示例给出了一个名为whoson的文件,其中包含shell脚本:
$ cat whoson $ whoson |
将文件名whoson作为命令并不能执行它,这是因为用户还不具备这个文件的执行权限。shell并不认同whoson是一个可执行文件,因此当用户试图执行它时就会出现一条错误消息。如果将该文件名作为bash的参数(bash whoson),那么bash将该参数作为一个shell脚本并执行它。这时,bash是可执行的,而whoson是bash将要执行的参数,因此用户不必具备whoson的执行权限。同样,也可以这样使用tcsh脚本文件。
命令未找到?
提示 如果看到下面的消息:
$ whoson
bash: whoson: command not found
shell并不在当前工作目录下面查找可执行文件。而如果按照下面的格式输入这条命令:
$ ./whoson
./明确地告诉shell,在当前工作目录下面查找可执行文件。为了修改shell环境,让shell能够自动在当前工作目录下面查找命令,请参见第8.3.3节。
chmod实用程序可以改变文件关联的访问权限。图8-1给出了带-l选项的ls命令的执行结果,该命令显示了文件whoson在使用chmod命令修改该文件所有者的可执行权限前后的访问权限。
|
| 图8-1 使用chmod命令将shell脚本变成可执行文件 |
在第1个ls命令的显示结果中,第4个字符为连字符(-),它指出该文件的所有者没有执行该文件的权限。接下来的chmod命令赋予了文件所有者可执行权限:u+x指示chmod为文件所有者(u)添加可执行权限(x)。u代表user,尽管它表示该文件的所有者(owner),但该所有者并不是在任何时候都是该文件的用户(user)。第2个参数是该文件的文件名。在第2个ls命令的显示结果中,第4个字符是x,指出文件所有者具备执行权限。
如果其他用户也要执行这个文件,就必须改变该文件的组访问权限和其他用户访问权限。任何用户要想把文件名作为命令执行,都必须具备执行访问权。如果该文件是一个shell脚本,用户尝试执行这个文件时,还必须具备读访问权限。而在执行一个二进制可执行文件(已编译程序)时,并不需要读访问权限。
图8-1中的最后一条命令给出了shell将文件名作为命令执行的情况。要想进一步了解这方面的内容,请参见第4.4节和第Ⅴ部分的ls和chmod。
2. #!指定shell
在shell脚本文件的第1行可以放置一行特殊的字符串,告诉操作系统使用哪个shell来执行这个文件。因为操作系统在试图exec(execute,执行)文件之前将检查该程序的开头字符串,这些字符让操作系统不必进行失败的尝试。如果脚本的前两个字符是#!,那么系统将这两个字符后面的那些字符作为用来执行该脚本的命令解释器的绝对路径名。它可以是任何程序的路径名,而并不仅仅是shell。下面的示例指定由bash来运行这个脚本:
$ cat bash_script |
如果想在不同于启动脚本shell的其他shell中运行脚本,那么,#!字符就可以派上用场。下面的示例给出了一个应该由tcsh执行的脚本:
$ cat tcsh_script |
因为有#!这么一行字符,所以操作系统可以确定由tcsh来执行这个脚本,而不管用户当前正在运行的shell。
在shell脚本中可使用ps –f来显示正在执行该脚本的shell的名字。下面的示例中ps显示的3行内容给出了运行父shell的进程、运行tcsh脚本的进程以及运行ps命令的进程:
$ cat tcsh_script2 $ tcsh_script2 |
如果在#!后面没有可执行程序名,shell将报告一个错误,通知没有找到用户要求运行的命令。在#!后面可以有一些空格。如果忽略#!那一行而试图运行脚本,比如从bash中运行tcsh脚本,shell将产生错误消息或者脚本执行不正确。
参见第13.5节中的一个独立的sed脚本,它用到了#!。
3. #开始一行注释
使用注释可使shell脚本和程序便于自己和他人阅读和维护。Bourne Again shell和TC Shell的注释语法相同。
如果#号(#)在脚本的第1行出现并且其后没有感叹号!,或者脚本中其他任意位置上出现了#,那么shell将其视为注释的开始。shell将忽略#到该行末(下一个换行符)之间的所有内容。
4. 执行shell脚本
fork和exec系统调用 用户在命令行上输入一条命令之后,shell将fork一个新的进程,以创建当前shell进程的一个副本(子shell)。这个新的进程将试图exec(execute,执行)该命令。与fork一样,exec例程也是由操作系统执行(系统调用)。
如果该命令是一个二进制可执行程序,比如编译好的C程序,那么exec执行成功,系统使用该可执行程序覆盖新创建的子shell。而如果这个命令是一个shell脚本,exec执行失败。当exec失败时,将会假设该命令是一个shell脚本,子shell将执行脚本中的命令。与登录shell期望从命令行读取输入不同,子shell从文件(shell脚本)中获取输入。
如前所述,如果不具备shell脚本文件的执行权限,那么,用户可以使用bash命令来exec一个shell直接运行该脚本,这样就可以运行脚本中的命令。在下面的示例中,bash创建了一个新的shell,它从名为whoson的文件中获取输入:
$ bash whoson |
因为bash命令期望读取一个包含命令的文件,所以不需要whoson的执行权限(但仍然需要读权限)。即便bash从whoson中读取并执行命令,标准输入、标准输出和标准错误输出仍然连接到终端。
尽管可以使用bash执行脚本,但这项技术将会使脚本的执行速度要比具备执行权限之后直接调用脚本慢一些。用户更喜欢将文件改为可执行并在命令行上直接输入文件名来运行脚本。而且输入名字更加容易一些,这和调用其他类型的程序的实践经验是一致的,这样用户就没有必要知道正在运行的是一个shell脚本还是其他类型的程序。然而,如果bash并不是用户所用的交互式shell或者想看看不同shell如何执行该脚本,那么就可将脚本作为bash或者tcsh的参数。
sh不能调用原Bourne Shell
警告 用命令sh调用原Bourne Shell。尽管可以在sh命令中调用bash,但它不是原Bourne Shell。sh命令(/bin/sh)为/bin/bash的符号链接,因此它仅仅是bash命令的另一个名字而已。当使用命令sh来调用bash时,bash试图尽可能地模仿原Bourne Shell的行为。但是这并不总能够成功。
| 回书目 上一节 下一节 |
|
· 2008年5月24日软考试题.. · 软件设计师专家临考模.. · 上周网络管理员专家自.. · 网络工程师自测获奖名.. · 08年4月各大网上书店及.. · 系统分析师自测获奖名.. |
· Linux结课考试自测获奖.. · 上周Linux系统命令的使.. · 上周真题冲刺测试获奖.. · 全国计算机等考四级模.. · 08年3月各大网上书店及.. · 网络工程师模拟测试获.. |
|
||||
| · 勇闯IT培训黑色围城 · IPv6协议--拓展网络无.. · 了解统一威胁管理(UTM).. · 调查:十大发现 解秘技.. · 技术人求职简历完备手册 · Vista SP1对决XP SP3 · 运营商封堵ADSL共享 中.. · LAMP技术精解 |
· PHP开发应用手册 · 解析35岁技术人的价值.. · 汶川大地震 IT技术人在.. · SOA 面向服务架构 · 龙芯要做中国的“奔腾” · 微软出价446亿美元收购.. · 网管员如何踏上高薪之路 · 主流品牌防火墙配置 |
|||
|
||||
| · SQL Server 2008/2005.. · SOA 面向服务架构 · SQL Server 2008/2005.. · iSCSI应用与发展 · RAID——磁盘阵列基础 · Apache技术专题 · 三层交换技术专题 · SQL Server入门到精通 |
· Apache技术专题 · 国际文档格式标准开战 · 路由器设置与口令恢复 · 打造安全服务器 · PHP开发应用手册 · SOA 面向服务架构 · 企业数据恢复指南 · ADSL应用面面俱到 |
|||
|
||||
| · iSCSI应用与发展 · SQL Server入门到精通 · SQL Server 2008/2005.. · SOA 面向服务架构 · Apache技术专题 · iSCSI应用与发展 · 三层交换技术专题 · Apache技术专题 |
· RAID——磁盘阵列基础 · 企业数据恢复指南 · 路由器设置与口令恢复 · SOA 面向服务架构 · 了解统一威胁管理(UTM).. · ADSL应用面面俱到 · ADSL应用面面俱到 · 反垃圾邮件技术应用 |
|||