0%

param

1. 特殊参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 扩展为位置参数, 从 1 开始.
如果扩展发生在双引号中, 它扩展为一个词, 值是各个参数, 以特殊变量 IFS 的第一个字符分隔.
也 就是说, "$*" 等价于 "$1c$2c...", 这里 c 是变量 IFS 的第一个字符.
如果没有设置 IFS, 那么参数将用空格分隔.
IFS
$*
# 扩展为位置参数, 从 1 开始.
如果扩展发生在双引号中, 每个参数都将扩展为一个词.
也就是说, "$@" 等价于 "$1" "$2" ... 如果位置参数不存在, "$@"$@ 扩展为空 (即, 它们被删除了).

$@
# 扩展为位置参数的个数, 以十进制表示.

$#
# 扩展为最近执行的前台管道的状态.

$?
# 扩展为当前选项标志.
标志是在启动时或以内建命令 set 指定的, 或者是 shell 自身设置的 (例如选项 -i ).

$-
# 扩展为 shell 的进程 ID.
在一个 () 子 shell 中, 它扩展为当前 shell 的 进程 ID 而不是子 shell 的.

$$
# 扩展为最近一次执行的后台 (异步) 命令的进程号.

$!
# 扩展为 shell 或者 shell 脚本的名称.
这个变量是在 shell 初始化时设置的.
如果 bash 是执行脚本文件时启动的, $0 将设置 为那个文件的名称.
如果 bash 启动时的参数包含 -c, 那么 $0 被设置为启动命令行被执行后的第一个参数, 如果有的话.
否则, 它被设置为用来启动 bash 的文件名, 就是参数 0.

$0
# shell 启动时, 设置为 shell 或参数中被执行的 shell 脚本的绝对路径名.
然后, 在扩展时扩展为上一个命令的最后一个参数.
它也被设置为被执行的每个命令的文件全名并且 被设置到这个命令执行的环境当中.
当检查邮件时, 这个参数保存着正在检查的邮件文件的名称.

$_

2. 参数表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# Use Default Values(使用默认值).
如果 parameter 未定义或值为空, 将替换为 word 的扩展.
否则, 将替换为 parameter 的值.

${parameter:-word}
# Assign Default Values(赋默认值).
如果 parameter 未定义或值为空, word 的扩展将赋予 parameter. parameter 的值将被替 换.
位置参数和特殊参数不能用这种方式赋值.

${parameter:=word}
# Display Error if Null or Unset(显示错误, 如果未定义或值为空).
如果 parameter 未定义或值为空, word (或一条信息, 如果 word 不存在) 的扩展将写入到标准错误; shell 如果不是交互的, 则将退出.
否则, parameter 的值将被替换.

${parameter:?word}
# Use Alternate Value(使用可选值).
如果 parameter 未定义或非空, 不会进行替换; 否则将替换为 word 扩展后的值.

${parameter:+word}
# Substring Expansion(子字符串扩展).
扩展为parameter 的最多 length 个字符, 从 offset 指定的字符开始.
如果忽略了 length, 扩展为 parameter 的子字符串, 从 offset 指定的字符串开始.
length 和 offset 是算术表达式 (参见下面的 ARITHMETIC EVALUATION 算术求值 段落).
length 必须是一个大于等于 0 的数值.
如果 offset 求值结果小于 0, 值将当作从 parameter 的值的末尾算起的偏移量.
如果 parameter 是 @, 结果是 length 个位置参数, 从 offset 开始.
如果 parameter 是 一个数组名, 以 @ 或 * 索引, 结果是数组的 length 个成员, 从 ${parameter[offset]} 开始.
子字符串的下标是从 0 开始 的, 除非使用位置参数时, 下标从 1 开始.

${parameter:offset}
${parameter:offset:length}
# 扩展为名称以 prefix 开始的变量名, 以特殊变量 IFS 的第一个字符分隔.

${!prefix*}
# word 被扩展为一个模式, 就像路径扩展中一样.
如果这个模式匹配 parameter 扩展后的值的尾部, 那么扩展的结果是将 parameter 扩展后的值中, 最短的匹配 (``%'' 的情况) 或者最长的匹配 (``%%''的情况) 删除的结果.
如果 parameter 是 @ 或者是 *, 则模 式删除操作将依次施用于每个位置参数, 最后扩展为结果的列表.
如果 parameter 是一个数组变量, 下标是 @ 或者是 *, 模式删除 将依次施用于数组中的每个成员, 最后扩展为结果的列表.

${parameter%word}
${parameter%%word}
# patterm 被扩展为一个模式, 就像路径扩展中一样.
parameter 被扩展, 其值中最长的匹配 pattern 的内容被替换为 string.
在 第一种形式中, 只有第一个匹配被替换.
第二种形式使得 pattern 中所有匹配都被替换为 string.
如果 pattern 以 # 开始, 它 必须匹配 parameter 扩展后 值的首部.
如果 pattern 以 % 开始, 它必须匹配 parameter 扩展后值的尾部.
如果 string 是空 值, pattern 的匹配都将被删除, pattern 之后的 / 将被忽略.
如果 parameter 是 @ 或者是 *, 则替换操作将依次施用于每个位 置参数, 最后扩展为结果的列表.
如果 parameter 是一个数组变量, 下标是 @ 或者是 *, 模式删除将依次施用于数组中的每个成 员, 最后扩展为结果的列表.

${parameter/pattern/string}
${parameter//pattern/string}

3. 事件指示器

事件指示器 (event designator) 是一个对历史列表中某个命令行条目的引用.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 开始一个命令替换, 除非后面跟随的是 blank, newline, = 或是 (.
!
# 引用命令行 n.
!n
# 引用当前命令行减去 n.
!-n
# 引用上一条命令.
这是 `!-1' 的同义词.

!!
# 引用最近的以 string 开始的命令.

!string
# 引用最近的包含 string 的命令.
尾部的 ? 可以被忽略, 如果 string 之后紧接着一个新行符.

!?string[?]
# 快速替换.
重复上一条命令, 将 string1 替换为 string2. 与 ``!!:s/string1/string2/'' 等价
^string1^string2^

4. 词指示器

词指示器 (word designator) 用于从 event 中选择期望的词.
分隔 event 规则与 word 指示器.
它可以忽略, 如果词指示器以 ^, $, *, -, 或 % 开始.
词被从行首开始编号, 第一个词被表示为 0.
插入当前行中的词以单个空格分隔.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 第 0 个词.
对 shell 来将, 这是命令名.

0
# 第 n 个词.

n
# 第一个参数.
也就是, 第 1 个词.

^
# 最后的参数.

$
# 最近一次搜索 `?string?' 匹配的词.

%
x
# 所有词, 除了第 0 个.
这是 `1-$' 的同义词.
如果 event 中只有一个词, 使用 * 也不是错误; 这种情况下将返回空字符串.
-y 一组词; `-y' 是 `0-y' 的简写.

*
# x-$ 的简写.

x*
# -$ 的简写, 就像 x* 一样, 但是忽略最后一个词.

x-

如果给出了一个 word 指示器, 没有给出 event 规则, 前一个命令将用作 event.

5. 常见问题

5.1. 脚本中使用 exit 1 会退出会话

检查 .bashrc 等地方是否设置了 set -e

6. Resources