将退出代码分配给 shell 局部变量

将退出代码分配给 shell 局部变量
#!/bin/bash
function0()
{
 local t1=$(exit 1)
 echo $t1
}

function0

echo打印空值。我期望:

1

为什么变量没有t1被分配退出命令的返回值 - 1

答案1

local t1=$(exit 1)告诉 shell:

  • exit 1在子 shell 中运行;
  • 将其输出(如输出到标准输出的文本)存储在t1函数本地的变量中。

因此,t1最终变成空的也是正常的。

$()被称为命令替换.)

退出代码始终分配给$?,因此您可以执行以下操作

function0()
{
  (exit 1)
  echo "$?"
}

以获得您想要的效果。您当然可以分配$?给另一个变量:

function0()
{
  (exit 1)
  local t1=$?
  echo "$t1"
}

答案2

退出代码存储在$?多变的。使用命令替换仅捕获输出,您应该使用(...) 创建子shell:

#!/bin/bash

func() {
  (exit 1)
  local t1=$?
  printf '%d\n' "$t1"
}

func

答案3

bash这部作品中:

loc(){  local   "x=$(exit "$1"):$?"
        printf  '$%s:\t%d\n' \
                 x "${x##*:}" \? "$?"
}

它与命令评估和变量分配的顺序有关。local有一个自己的返回值 - 它是当前正在执行的命令,而不是命令替换。原因就像...

x=$(exit 1); echo "$?"

$x...可以返回 1 是因为除了运行子 shell 来分配值之外,该命令中永远不会返回- 因此$?不会像在使用命令替换的几乎所有其他情况下那样被破坏。

无论如何,有了local被破坏 - 但如果你在正确的时间抓住它 - 即扩展仍在评估中并且 local的例程有机会破坏它 - 你仍然可以分配它。

unset x; loc 130; echo "${x-\$x is unset}"

...印刷...

$x: 130
$?: 0
$x is unset

但您应该知道,在许多 shell 中,您不能依赖以$?这种方式进行中间评估。事实上,这可能是因为这些 shell 不会像可能bash那样在每个可能的时刻重新评估 - 我认为这可能是比 更好的行为bash。您是否真的希望您的解释器递归循环评估很可能在您有机会使用它们之前被覆盖的值?

无论如何,这就是你可以做到的。

答案4

@mikeserv 的答案很棒,并为我发现但不知道为什么会发生的行为提供了解释。

我只是想添加一个简单的方法来避免local吃掉子 shell 的退出代码:

val_check_exit() {
   local val=
   val=$(echo "hi"; exit 1)
   local res=$?
   echo "val is ${val}, exit code ${res}"
}
val_check_exit
# outputs:
# val is hi, exit code 1

相关内容