通过eval和函数保留bash返回代码

通过eval和函数保留bash返回代码,bash,Bash,我有一个简单的bash函数,hle(突出显示错误),它在构建时突出显示重要的文本。其实施情况如下: hle() ( set -o pipefail "$@" 2>&1 | sed -f $hldir/red.sed -f $hldir/blue.sed -f $hldir/orange.sed ) 因此,您可以运行hle make target,所有错误将显示为红色,警告为橙色,调试为蓝色 现在,我有一个这样的脚本: foo.sh: eval hl

我有一个简单的bash函数,
hle
(突出显示错误),它在构建时突出显示重要的文本。其实施情况如下:

hle() (
  set -o pipefail
  "$@" 2>&1 |
  sed -f $hldir/red.sed -f $hldir/blue.sed -f $hldir/orange.sed
)
因此,您可以运行hle make target,所有错误将显示为红色,警告为橙色,调试为蓝色

现在,我有一个这样的脚本:

foo.sh:

eval hle $command
[ $? ] && echo "SUCCESS"

但是这不起作用,因为
$?
表示eval的返回代码(我相信这是hle本身的返回代码…)我如何在脚本中保存
$命令的返回代码?

正如您所发现的,您对
hle
的实现应该已经得到正确的退出代码。但是,测试
[$?]
是有缺陷的。使用
[$?=0]
时,它应该可以正常工作

然而,这里有一个
hle
的替代实现,它不需要更改
set-o
选项,因此也不需要子shell:

hle() {
  "$@" 2>&1 |
  sed -f "$hldir/red.sed" -f "$hldir/blue.sed" -f "$hldir/orange.sed"
  return "${PIPESTATUS[0]}"
}
对于
eval
,退出状态为已评估命令的状态,请参阅:

eval[参数]

这些参数被连接到一个命令中,然后读取并执行该命令,其退出状态作为eval的退出状态返回


顺便说一下:根据
$command
的不同,您根本不需要
eval
。好的,我只能想到一种情况,
eval
非常重要,即管道(
command=“cmd1 | cmd2”
)。但是,在这样的管道中,只有第一个命令将由
hle
执行。如果您确实需要
eval
,则将其放入函数(
{eval“$@”}2>&1 |
)。

正如您所发现的,您的
hle
实现应该已经得到正确的退出代码。但是,测试
[$?]
是有缺陷的。使用
[$?=0]
时,它应该可以正常工作

然而,这里有一个
hle
的替代实现,它不需要更改
set-o
选项,因此也不需要子shell:

hle() {
  "$@" 2>&1 |
  sed -f "$hldir/red.sed" -f "$hldir/blue.sed" -f "$hldir/orange.sed"
  return "${PIPESTATUS[0]}"
}
对于
eval
,退出状态为已评估命令的状态,请参阅:

eval[参数]

这些参数被连接到一个命令中,然后读取并执行该命令,其退出状态作为eval的退出状态返回


顺便说一下:根据
$command
的不同,您根本不需要
eval
。好的,我只能想到一种情况,
eval
非常重要,即管道(
command=“cmd1 | cmd2”
)。但是,在这样的管道中,只有第一个命令将由
hle
执行。如果您确实需要
eval
,请将其放入函数(
{eval“$@”}2>&1 |
)。

对不起,在与@Socowi交谈后,我发现问题不在于eval或函数,而在于测试

在脚本中,
eval hle$command
的返回值实际上与
command
的返回值相同。我的问题是
[$?]&echo SUCCESS
$?
解析为
1
0
,这在
测试中始终被认为是正确的。正确的路线应该是:

eval hle $command
[ $? == 0 ] && echo "SUCCESS"

很抱歉,在与@Socowi交谈之后,我发现问题不在于评估或函数,而在于测试

在脚本中,
eval hle$command
的返回值实际上与
command
的返回值相同。我的问题是
[$?]&echo SUCCESS
$?
解析为
1
0
,这在
测试中始终被认为是正确的。正确的路线应该是:

eval hle $command
[ $? == 0 ] && echo "SUCCESS"

这似乎有效:
eval-hle-false;echo$?;评价正确;echo$?
给出了
1
0
我刚刚发现,我的原始解决方案也通过了上述测试——问题在于
[$?]和&
——如果它是
0
1
,则将
$?
视为真的。。。。叹息…
eval-hle-false;[$?]&&echo true
echos
true
,但
eval-hle-false;[$?==0]&&echo true
有效properly@HardcoreHenry*facepalm*谢谢你让我知道。我已经想知道为什么
pipefail
不适合您,但从未想过
[$?]
部分。我将你的发现添加到这个答案中以使其完整。这似乎有效:
eval-hle-false;echo$?;评价正确;echo$?
给出了
1
0
我刚刚发现,我的原始解决方案也通过了上述测试——问题在于
[$?]和&
——如果它是
0
1
,则将
$?
视为真的。。。。叹息…
eval-hle-false;[$?]&&echo true
echos
true
,但
eval-hle-false;[$?==0]&&echo true
有效properly@HardcoreHenry*facepalm*谢谢你让我知道。我已经想知道为什么
pipefail
不适合您,但从未想过
[$?]
部分。我将您的发现添加到此答案中以使其完整。请尝试使用
[[[$?-ne 0]]| | echo“SUCCESS”
。该行的退出状态将为0,如果您想在Makefile中使用代码,或者设置了
set-e
,则可以使用该行。请尝试使用
[[[$?-ne 0]]| echo“SUCCESS”
。该行的退出状态将为0,如果您想在Makefile中使用代码或设置了
set-e
,这将非常有用。