Bash¶
约 105 个字 预计阅读时间不到 1 分钟
这是一个「博客式」主题
该主题下的内容会以「博客式」的方式组织。也就是说,该主题并不打算组织成一部「教科书」:每篇文章都是独立、自洽、解决一个特定问题的,用户不需要按照特定的顺序阅读。同时,该主题也不保证从零开始、不保证完整详尽。
这不代表该主题下内容的质量会变差,我仍将尽力保证每篇文章能清晰地说明一个技术或者解决方案。同时,我会尽可能注明每篇文章的前置知识,以及后续的拓展阅读。
我会随着自己的学习进程和需求更新这个主题的内容。
管道和 xargs
find . -name '*.py' | xargs wc -l
Bash is an acronym for ‘Bourne-Again SHell’. The Bourne shell is the traditional Unix shell originally written by Stephen Bourne.
Pipelines¶
Pipelines 是用 |
或 |&
连接起来的一系列 commands。一个单独的 command 也算一个 pipeline。
管道 (pipe) |
和 |&
用于将一个命令的输出传递给另一个命令的输入。
如果使用 |
,则将命令的标准输出 (stdout) 传递给另一个命令的标准输入 (stdin);如果使用 |&
,则将命令的标准输出 (stdout) 和标准错误 (stderr) 传递给另一个命令的标准输入。
Example
#!/bin/sh
echo "stdout"
echo "stderr" >&2
#!/bin/sh
while IFS= read -r line
do
echo "from stdin: $line"
done
效果
% cd examples/common_scripts
% ./print.sh | ./read.sh
stderr
from stdin: stdout
% ./print.sh |& ./read.sh
from stdin: stdout
from stdin: stderr
请注意:以 |
连接的命令是并行执行的。例如:
% (sleep 1 ; >&2 echo "1") | echo "2"
2
1
显然,并行执行会在不同的 sub shell 中执行:
% echo $BASHPID
29823
% >&2 echo $BASHPID | echo $BASHPID
30402
30401
另需注意的是,默认情况下 pipeline 中的命令失败不会导致整个 pipeline 停止和失败;pipeline 的返回值是最后一个命令的返回值。例如:
% false | echo "This will be printed"
This will be printed
% echo $?
0
为了避免错过可能的错误,可以使用 set -o pipefail
。此时如果有任何命令失败,整个 pipeline 的返回值就是最后一个失败的命令的返回值。
% set -o pipefail
% false | echo "This will still be printed"
This will still be printed
% echo $?
1
% exit 1 | exit 2 | echo "This will still be printed"
This will still be printed
% echo $?
2
See Also:
- TODO:
|&
是2>&1 |
的缩写。 - TODO: time
- TODO: Each command in a multi-command pipeline, where pipes are created, is executed in its own subshell, which is a separate process (see Command Execution Environment)
List of Commands¶
List 是用 ;
, ||
, &&
, &
或换行连接起来的一系列 commands。一个单独的 command 也算一个 list。一个 list 可选地以 ;
, &
或换行结尾。
本节使用的示例脚本
#!/bin/sh
echo "succeed"
exit 0
#!/bin/sh
echo "fail"
exit 1
由换行或 ;
连接起来的 2 个 pipeline 会顺次执行,返回值为其中最后一个命令的返回值。
效果
% ./fail.sh ; ./succeed.sh
fail
succeed
% echo $?
0
% ./succeed.sh ; ./fail.sh
succeed
fail
% echo $?
1
由 &&
连接起来的 2 个 pipeline 会顺次执行,当且仅当第一个 pipeline 成功时才会执行第二个 pipeline。返回值为最后一个执行了的命令的返回值。
效果
% ./fail.sh && ./succeed.sh
fail
% echo $?
1
% ./succeed.sh && ./fail.sh
succeed
fail
% echo $?
1
由 ||
连接起来的 2 个 pipeline 会顺次执行,当且仅当第一个 pipeline 失败时才会执行第二个 pipeline。返回值为最后一个执行了的命令的返回值。
效果
% ./fail.sh || ./succeed.sh
fail
succeed
% echo $?
0
% ./succeed.sh || ./fail.sh
succeed
% echo $?
0
% ./fail.sh || ./fail.sh
fail
fail
% echo $?
1