如何让`local` 捕获退出代码?

Ult*_*awk 12 bash variable exit-status

在我的项目中,我有以下代码段:

local output="$(bash "${1##*/}")"
echo "$?"
Run Code Online (Sandbox Code Playgroud)

这总是打印零,因为local,但是,删除local会导致$?变量正确运行:假设子shell 的退出代码。

我的问题是:如何在捕获退出值的同时保持这个变量本地化?

Wil*_*ard 29

在分配给它之前声明局部变量:

thing() {
  local output
  output="$(bash "${1##*/}")"
  echo "$?"
}
Run Code Online (Sandbox Code Playgroud)

在我看来,这也比设置附加RET变量更具可读性。YMMV,但它的工作原理与您期望的一样。

  • 这比使用单独的变量*好得多,如果您想检查多个赋值的返回码,这应该很明显:只需`local var1 var2 ...`,Bob 是你的叔叔。 (2认同)

Dop*_*oti 19

#!/bin/bash
thing() {
   local foo=$(asjkdh) ret="$?"
   echo "$ret"
}
Run Code Online (Sandbox Code Playgroud)

这将 echo 127,“未找到命令”的正确错误代码。

您可以使用local来定义多个变量。所以我也只是创建了局部变量RET来在local成功之前捕获子shell的退出代码并设置$?为零。

  • 顺便说一句,使用全大写的变量名是不好的形式。请参阅 http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html 上的 POSIX 环境变量规范,该规范将全大写名称描述为保留给对 shell 或系统有意义的变量,名称带有 at至少一个小写字符保留用于应用程序定义的用途,请记住 shell 变量和环境变量共享一个命名空间(因为在发生冲突时,分配给前者可以覆盖后者)。 (10认同)