3.8 Shell脚本
shell脚本是一个包含shell命令的文本文件。当调用Bash时,这样的文件被用作第一个非选项参数,并且既没有提供-c也没有提供-s选项(见6.1 调用Bash),Bash会读取并执行该文件的命令,然后退出。这种操作模式创建了一个非交互式的shell。shell首先在当前目录下搜索该文件,如果没有找到,则在$PATH
的目录中寻找。
当Bash运行一个shell脚本时, 它将特殊参数0
设置为文件名, 而不是shell的名称, 并且将位置参数设置为其余的参数,如果有的话。如果没有提供额外的参数,则位置参数未设置。
一个shell脚本可以通过使用chmod
命令打开execute位来实现可执行。当Bash在搜索$PATH
命令时发现这样一个文件,它就会创建一个新的实例来执行它。 换句话说,执行
filename arguments
相当于执行了
bash filename arguments
如果filename
是一个可执行的shell脚本,这个子shell就会重新初始化自己,这样的效果就像一个新的shell被调用来解释这个脚本一样,但例外的是,父级记住的命令的位置(见4.1 Bourne Shell内置程序中对hash
的描述)被子级保留了。
大多数版本的Unix将此作为操作系统命令执行机制的一部分。如果一个脚本的第一行以‘#!’这两个字符开头,该行的其余部分就会为程序指定一个解释器,并且根据操作系统的不同,为该解释器指定一个或多个可选的参数。 因此,你可以指定Bash、awk
、Perl或其他一些解释器,并且用该语言编写脚本文件的其余部分。
解释器的参数由脚本文件第一行的解释器名称后面的一个或多个可选的参数组成,然后是脚本文件的名称,接着是提供给脚本的其余参数。 解释器行如何被分割成一个解释器名称和一组参数的细节在不同的系统中有所不同。Bash会在没有自己处理的操作系统上执行这个动作。 注意,一些旧版本的Unix将解释器名称和单个参数限制在32个字符以内,因此假设使用多个参数会起作用是不可移植的。
Bash脚本通常以#! /bin/bash
开头(假设Bash已经安装在/bin中),因为这可以确保Bash会被用来解释脚本,即使它是在其他shell下执行的。使用env
来查找bash
是一个常见的习惯,即使它被安装在另一个目录中:#!/usr/bin/env bash
会在$PATH
中找到bash
的第一次出现。