如何使“本地”捕获退出代码?


11

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

local output="$(bash "${1##*/}")"
echo "$?"

由于local,这始终显示为零,但是,删除local会导致$?变量正确运行:这是假定从子shell退出代码。

我的问题是:如何在保留退出值的同时保持局部变量不变?


1
shellcheck不仅会解决此问题,还会unix.stackexchange.com/a/281749/24718中提出解决方案!
瓦里德·汗

Answers:


16
#!/bin/bash
thing() {
   local foo=$(asjkdh) ret="$?"
   echo "$ret"
}

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

您可以local用来定义多个变量。因此,我还创建了局部变量,RET以在local成功并将其设置$?为零之前捕获子外壳程序的退出代码。


是否可以保证bash从左到右评估该表达式?
马克斯·里德

据我所知,在这种情况下,变量分配是从左到右的顺序,是的。
DopeGhoti

@MaxRied这个工作可靠的事实似乎表明是的。但是,从POSIX和bash参考手册中都找不到关于此的信息。

10
顺便说一句,使用全大写字母的变量名是不好的形式。请参阅pubs.opengroup.org/onlinepubs/009695399/basedefs/…上的POSIX环境变量规范,其中描述了所有大写名称,这些名称保留给具有外壳程序或系统含义的变量,以及至少具有一个小写字符的名称。保留供应用程序定义的使用,请牢记shell变量和环境变量共享一个名称空间(因为在发生冲突的情况下,分配给前者可以覆盖后者)。
查尔斯·达菲

评论不作进一步讨论;此对话已转移至聊天
terdon

27

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

thing() {
  local output
  output="$(bash "${1##*/}")"
  echo "$?"
}

在我看来,这比设置其他RET变量更具可读性。YMMV可以做到这一点,但是它可以按照您的期望工作。


2
这比使用单独的变量好得多,这很明显,如果您要检查多个任务的返回码:简单地local var1 var2 ...和鲍勃是您的叔叔。
l0b0

@ l0b0鲍勃我的叔叔。:D
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.