3.8 Shell 脚本(Shell Scripts)
Shell 脚本就是一个包含了若干 shell 命令的文本文件。当调用 Bash 即没有加“-c”也没有加“-s”选项时,其后跟随的第一个非选项参数是一个文件时,Bash 会从文件中读取命令并执行,然后退出。这种操作模式创建一个非交互式的 shell。shell 首先会在当前目录搜索这个文件,如果没有找到,则在变量“$PATH”中查找。
当 Bash 运行一个 shell 脚本时,其会将特殊参数“0”设置为这个文件的文件名,而不是 shell 名。并且如果给出了后继的参数,则将位置参数设置为这些参数。如果没有提供附加的参数,则不对位置参数进行设置。
使用 chmod 命令开启执行位标记,将 shell 脚本设置为可执行的。当 Bash 在“$PATH”中搜索命令时找到了这样的文件,它将孵化出一个用于执行该脚本的子 shell。换句话说,如果“filename”是可执行的 shell 脚本的话,则执行
filename arguments
等同于执行
bash filename arguments
这个子 shell 重新初始化其自身,所以产生的效果就像调用一个新 shell 来解释这个脚本。其不同的是由其父 shell(参考 4.1 节《Bourne Shell 内建命令》的 hash》)记住的命令位置都保留给了子 shell。
大多数的 Unix 版本将其归为操作系统执行命令机制的一部分。如果脚本的第一行由“#!”两个字符开头,则这行剩下的部分用于指定程序的解释器。并且依赖于操作系统,可以为解释器加入一个或多个可选的参数。因此,你可以在第一行指定使用 Bash、awk、Perl 或其它解释器,在脚本剩下的部分使用这种语言进行编写。
解释器的参数是由脚本文件第一行中的解释器名后的一个或多个可选参数,解释器后的脚本文件名,以及向脚本提供的剩余参数组成的。不同的系统有不同的方法将解释器行分隔为解释器名和参数集。Bash 会在操作系统不能处理该动作时自己执行这个动作。注意,一些老版本的 Unix 会限制使用解释器名和单个参数的总长度最大不能超过 32 个字符。所以超过一个参数会使脚本的移植性变差。
Bash 脚本经常使用“#! /bin/bash”开头(假设 Bash 被安装到了“/bin”路径下面),这样一来即使其执行在其它 shell 下,也可以确保使用 Bash 作为这个脚本的解释器。这有一种公用的方式,使用“env”命令来寻找“bash”命令,即使其被安装到了其它目录。“#! /usr/bin/env bash”将在“$PATH”中寻找第一个出现的 bash 命令。