调用命令

检查返回值

Tip

总是检查返回值,并给出信息返回值。

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

例如:

  1. if ! mv "${file_list}" "${dest_dir}/" ; then
  2. echo "Unable to move ${file_list} to ${dest_dir}" >&2
  3. exit "${E_BAD_MOVE}"
  4. fi
  5.  
  6. # Or
  7. mv "${file_list}" "${dest_dir}/"
  8. if [[ "$?" -ne 0 ]]; then
  9. echo "Unable to move ${file_list} to ${dest_dir}" >&2
  10. exit "${E_BAD_MOVE}"
  11. fi

Bash也有 PIPESTATUS 变量,允许检查从管道所有部分返回的代码。如果仅仅需要检查整个管道是成功还是失败,以下的方法是可以接受的:

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

可是,只要你运行任何其他命令, PIPESTATUS 将会被覆盖。如果你需要基于管道中发生的错误执行不同的操作,那么你需要在运行命令后立即将 PIPESTATUS 赋值给另一个变量(别忘了 [ 是一个会将 PIPESTATUS 擦除的命令)。

  1. tar -cf - ./* | ( cd "${DIR}" && tar -xf - )
  2. return_codes=(${PIPESTATUS[*]})
  3. if [[ "${return_codes[0]}" -ne 0 ]]; then
  4. do_something
  5. fi
  6. if [[ "${return_codes[1]}" -ne 0 ]]; then
  7. do_something_else
  8. fi

内建命令和外部命令

Tip

可以在调用shell内建命令和调用另外的程序之间选择,请选择内建命令。

我们更喜欢使用内建命令,如在 bash(1) 中参数扩展函数。因为它更强健和便携(尤其是跟像 sed 这样的命令比较)

例如:

  1. # Prefer this:
  2. addition=$((${X} + ${Y}))
  3. substitution="${string/#foo/bar}"
  4.  
  5. # Instead of this:
  6. addition="$(expr ${X} + ${Y})"
  7. substitution="$(echo "${string}" | sed -e 's/^foo/bar/')"

原文: https://zh-google-styleguide.readthedocs.io/en/latest/google-shell-styleguide/calling_commands/