跳转至

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
examples/common_scripts/print.sh
#!/bin/sh
echo "stdout"
echo "stderr" >&2
examples/common_scripts/read.sh
#!/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 可选地以 ;, & 或换行结尾。

本节使用的示例脚本
examples/common_scripts/succeed.sh
#!/bin/sh
echo "succeed"
exit 0
examples/common_scripts/fail.sh
#!/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

颜色主题调整

评论区~

有用的话请给我个赞和 star => GitHub stars
快来跟我聊天~