Skip to Content
Shell调用命令

调用命令

检查返回值

始终检查返回值并给出有意义的返回值。

对于非管道命令,使用 $? 或通过 if 语句直接检查以保持简单。

示例:

if ! mv "${file_list[@]}" "${dest_dir}/"; then echo "Unable to move ${file_list[*]} to ${dest_dir}" >&2 exit 1 fi # Or mv "${file_list[@]}" "${dest_dir}/" if (( $? != 0 )); then echo "Unable to move ${file_list[*]} to ${dest_dir}" >&2 exit 1 fi

Bash 还有 PIPESTATUS 变量,允许检查管道中所有部分的返回码。 如果只需要检查整个管道的成功或失败,则以下方式是可以接受的:

tar -cf - ./* | ( cd "${dir}" && tar -xf - ) if (( PIPESTATUS[0] != 0 || PIPESTATUS[1] != 0 )); then echo "Unable to tar files to ${dir}" >&2 fi

但是,由于 PIPESTATUS 会在你执行任何其他命令后立即被覆盖, 如果你需要根据管道中错误发生的位置采取不同的操作, 你需要在运行命令后立即将 PIPESTATUS 赋值给另一个变量 (不要忘记 [ 是一个命令,会清除 PIPESTATUS)。

tar -cf - ./* | ( cd "${DIR}" && tar -xf - ) return_codes=( "${PIPESTATUS[@]}" ) if (( return_codes[0] != 0 )); then do_something fi if (( return_codes[1] != 0 )); then do_something_else fi

内建命令 vs. 外部命令

在调用 Shell 内建命令和调用外部进程之间做选择时,选择内建命令。

我们优先使用内建命令,例如 bash 提供的 参数展开(Parameter Expansion) 功能,因为它更高效、健壮和可移植(特别是与 sed 等工具相比)。 另请参见 =~ 运算符

示例:

# Prefer this: addition="$(( X + Y ))" substitution="${string/#foo/bar}" if [[ "${string}" =~ foo:(\d+) ]]; then extraction="${BASH_REMATCH[1]}" fi
# Instead of this: addition="$(expr "${X}" + "${Y}")" substitution="$(echo "${string}" | sed -e 's/^foo/bar/')" extraction="$(echo "${string}" | sed -e 's/foo:\([0-9]\)/\1/')"
Last updated on