|
| 1 | +# Bash 脚本的用法 |
| 2 | + |
| 3 | +Bash 脚本(script)就是一个包含一系列 Bash 命令的文件。Shell 读取这个文件,然后执行文件中的所有命令,就好像这些命令直接输入到命令行一样。所有能够在命令行中完成的任务,也能够用脚本来实现。 |
| 4 | + |
| 5 | +## Shebang 和脚本执行 |
| 6 | + |
| 7 | +脚本的第一行通常以`#!`字符开头,这个字符称为 Shebang,表示该文件是脚本。在 Shebang 后面是指定的脚本解释器,即使用什么程序执行该脚本,Bash 脚本的解释器一般是`/bin/sh`。 |
| 8 | + |
| 9 | +```bash |
| 10 | +#!/bin/sh |
| 11 | +``` |
| 12 | + |
| 13 | +如果用户的 Bash 可执行文件不在`/bin/sh`,脚本就无法执行了。为了保险,可以写成下面这样。 |
| 14 | + |
| 15 | +```bash |
| 16 | +#!/usr/bin/env bash |
| 17 | +``` |
| 18 | + |
| 19 | +上面命令使用`/usr/bin/env`命令,返回 Bash 的可执行文件。`env`命令的详细介绍,请看后文。 |
| 20 | + |
| 21 | +每个脚本都应包含一个 Shebang 行。如果缺少该行,就需要手动调用解释器。举例来说,脚本是`script.sh`,有 Shebang 行的时候,可以直接调用执行。 |
| 22 | + |
| 23 | +```bash |
| 24 | +$ ./script.sh |
| 25 | +``` |
| 26 | + |
| 27 | +如果没有 Shebang 行,就只能手动调用解释器执行。 |
| 28 | + |
| 29 | +```bash |
| 30 | +$ /bin/sh ./script.sh |
| 31 | +# 或者 |
| 32 | +$ bash ./script.sh |
| 33 | +``` |
| 34 | + |
| 35 | +上面命令中,最后一行的`bash`命令一般是`/bin/sh`的别名。 |
| 36 | + |
| 37 | +脚本如果要直接执行,除了必须有 Shebang 行以外,还需要有执行权限。可以使用下面的命令,赋予脚本执行权限。 |
| 38 | + |
| 39 | +```bash |
| 40 | +$ chmod +x ./script.sh |
| 41 | +``` |
| 42 | + |
| 43 | +脚本调用的时候,一般需要指定脚本的路径。如果将脚本放在环境变量`$PATH`指定的目录中,就不需要指定路径了。建议可以主目录里面新建一个`~/bin`目录,专门存放可执行脚本,然后把`~/bin`加入`$PATH`。 |
| 44 | + |
| 45 | +```bash |
| 46 | +$ script.sh |
| 47 | +``` |
| 48 | + |
| 49 | +上面的命令没有指定脚本路径,因为`script.sh`在`$PATH`指定的目录中。 |
| 50 | + |
| 51 | +## 注释 |
| 52 | + |
| 53 | +Bash 脚本中,`#`表示注释。 |
| 54 | + |
| 55 | +```bash |
| 56 | +# 本行是注释 |
| 57 | +echo 'Hello World!' |
| 58 | + |
| 59 | +echo 'Hello World!' # 井号后面的部分也是注释 |
| 60 | +``` |
| 61 | + |
| 62 | +## 别名 |
| 63 | + |
| 64 | +`alias`命令用来为命令指定别名。 |
| 65 | + |
| 66 | +```bash |
| 67 | +alias NAME=DEFINITION |
| 68 | +``` |
| 69 | + |
| 70 | +下面的例子是指定`ls -ltr`命令的别名为`lt`,运行结果是按照修改时间(`-t`)的倒序(`-r`),列出文件的详细信息(`-l`)。 |
| 71 | + |
| 72 | +```bash |
| 73 | +$ alias lt='ls -ltr' |
| 74 | +``` |
| 75 | + |
| 76 | +指定别名以后,就可以像使用其他命令一样使用别名。 |
| 77 | + |
| 78 | +直接调用`alias`命令,可以显示所有别名。 |
| 79 | + |
| 80 | +```bash |
| 81 | +$ alias |
| 82 | +``` |
| 83 | + |
| 84 | +`unalias`命令可以解除别名。 |
| 85 | + |
| 86 | +```bash |
| 87 | +$ unalias lt |
| 88 | +``` |
| 89 | + |
| 90 | +## env 命令 |
| 91 | + |
| 92 | +`env`命令总是在`/usr/bin`里面,它会在指定环境之中运行一个程序。`/usr/bin/env bash`的意思是,找到`bash`的可执行文件。 |
| 93 | + |
| 94 | +相应的,如果要执行Node脚本,可以写成下面这样。 |
| 95 | + |
| 96 | +```bash |
| 97 | +#!/usr/bin/env node |
| 98 | +``` |
| 99 | + |
| 100 | +`#!/usr/bin/env NAME`这种语法的意思是,命令 Shell 查找`$PATH`环境变量里面第一个匹配的`NAME`。如果你不知道某个命令的路径,这样的写法就很有用。它的好处是,只要`bash`的路径是在`$PATH`路径里面,就总是能找到它。 |
| 101 | + |
| 102 | +`env`命令的参数如下。 |
| 103 | + |
| 104 | +- `-i`, `--ignore-environment`:不带环境变量启动 |
| 105 | +- `-u`, `--unset=NAME`:从环境变量中删除一个变量 |
| 106 | +- `--help`:显示帮助 |
| 107 | +- `--version`:输出版本信息 |
| 108 | + |
| 109 | +下面是一个例子,新建一个不带任何环境变量的Shell。 |
| 110 | + |
| 111 | +```bash |
| 112 | +$ env -i /bin/sh |
| 113 | +``` |
| 114 | + |
| 115 | +## exit 命令 |
| 116 | + |
| 117 | +`exit`命令用于终止当前脚本的执行,并向 Shell 返回一个退出值。 |
| 118 | + |
| 119 | +```bash |
| 120 | +$ exit |
| 121 | +``` |
| 122 | + |
| 123 | +上面命令中止当前脚本,将最后一条命令的退出状态,作为整个脚本的退出状态。 |
| 124 | + |
| 125 | +`exit`命令后面可以跟参数,该参数就是退出状态。 |
| 126 | + |
| 127 | +```bash |
| 128 | +$ exit 1 |
| 129 | +``` |
| 130 | + |
| 131 | +退出时,脚本会返回一个退出值。脚本的退出值,`0`表示正常,`1`表示发生错误,`2`表示用法不对,`126`表示不是可执行脚本,`127`表示命令没有发现。如果脚本被信号`N`终止,则退出值为`128 + N`。简单来说,只要退出值非0,就认为执行出错。 |
| 132 | + |
| 133 | +上一条命令的退出值,可以用系统变量`$?`查询。使用这个命令,可以知道上一条命令是否执行成功。 |
| 134 | + |
| 135 | +`exit`与`return`命令的差别是,`return`命令是函数的退出,并返回一个值给调用者,脚本依然执行。`exit`是整个脚本的退出,如果在函数之中调用`exit`,则退出函数,并终止脚本执行。 |
| 136 | + |
0 commit comments