bash 编程与脚本
bash 不是“命令的集合”,而是一门完整语言:变量、条件、循环、函数、返回码都有。
返回码与短路
- 0 成功,非 0 失败,
$?是上一条命令的结果 &&成功才继续,||失败才执行if、while判断的是返回码
bash
mkdir /tmp/x && cd /tmp/x
grep -q pattern file && echo found条件
| 写法 | 说明 |
|---|---|
[ -f file ] | test 命令,方括号两侧要空格 |
[[ -f file ]] | bash 语法,支持 &&、` |
[ "$a" = "$b" ] | 字符串比较 |
[ "$n" -lt 10 ] | 数值比较 |
(( n++ )) | 算术展开 |
新脚本优先 [[ ]],它不会因为变量为空把语法拆坏。
位置参数
| 变量 | 含义 |
|---|---|
$0 | 脚本名 |
$1…$9 | 前九个参数 |
${10} | 第十个及以后 |
$# | 参数个数 |
$@ | 全部参数 |
"$@" | 每个参数保持独立 |
shift | 丢掉第一个参数并左移 |
脚本骨架
bash
#!/usr/bin/env bash
set -euo pipefail
log="run-$(date +%s).log"
while cargo test > "$log" 2>&1; do
echo passed
done
tail -n 20 "$log"| 部分 | 作用 |
|---|---|
| shebang | 指定解释器,env 会去 $PATH 找 |
set -e | 命令失败即退出 |
set -u | 未定义变量即退出 |
set -o pipefail | 管道任一段失败即失败 |
set -x | 打印展开后的命令 |
set -e 有边界:出现在 if 条件、&& 左值、! 后面的失败不会触发退出。
运行脚本
bash
chmod +x script.sh
./script.sh- 当前目录默认不在
$PATH bash script.sh不需要可执行位,但会另起一个 Shellsource script.sh在当前 Shell 执行- 权限位
755= 所有者读写执行,其他人读执行
函数与后台
bash
mkcd() { mkdir -p "$1" && cd "$1"; }
long_task & echo $!函数里默认是全局变量,要局部写 local。
脚本超过一百行、需要数据结构和错误处理时,换 Python 更省事。shellcheck 能提前发现大部分引号和返回码问题。