启用extdebug时Bash调试陷阱保留自定义退出值
我使用bash的debug trap操作命令并在debug trap函数中执行它们,同时阻止原始命令的执行。 这是由启用extdebug时Bash调试陷阱保留自定义退出值,bash,Bash,我使用bash的debug trap操作命令并在debug trap函数中执行它们,同时阻止原始命令的执行。 这是由 shopt -s extdebug 通过从陷阱返回1来阻止命令执行。但是,我希望将$?设置为命令的退出状态。相反,美元?总是零。请查看以下代码: dbgtrap(){ echo "command incoming: $BASH_COMMAND" [[ $BASH_COMMAND == 'echo $?' ]] && return 0 (e
shopt -s extdebug
通过从陷阱返回1来阻止命令执行。但是,我希望将$?
设置为命令的退出状态。相反,美元?总是零。请查看以下代码:
dbgtrap(){
echo "command incoming: $BASH_COMMAND"
[[ $BASH_COMMAND == 'echo $?' ]] && return 0
(exit 97)
return 1
}
shopt -s extdebug
trap 'dbgtrap' DEBUG
echo hi
echo $? # this should be 97 but is 0
当我愚蠢的自定义命令(退出97)
执行时,不会执行echo hi(这就是我想要的)。
下一个命令echo$?
是允许的,因为陷阱返回0。我希望$?
在此场景中为97。有办法吗
查尔斯·达菲回答
但不要介意:除非陷阱返回非零值(从而中止它们以前运行的命令),否则这很容易解决:
所以,我想在这种情况下,这不是那么容易-至少我还没有找到一种方法。有人吗?所以。。。您的“愚蠢的自定义命令”在子shell中执行,但正如所写,您的函数有两个可能的返回值,由return0
和return1
生成。这些返回值用于指导脚本命令的执行,在程序执行中不可用
也就是说,您可以在另一个变量中记录嵌入命令的返回值。例如:
#!/usr/bin/env bash
dbgtrap(){
printf 'incoming: _%s_\n' "$BASH_COMMAND"
[[ $BASH_COMMAND == *=* ]] && return 0
(exit 97)
declare -g stupidreturn=$?
echo "stupid worked: $stupidreturn"
return $stupidreturn
}
shopt -s extdebug
trap 'dbgtrap' DEBUG
echo hi
echo return=$?
echo stupid=$stupidreturn
结果:
incoming: _echo hi_
stupid worked: 97
incoming: _echo return=$?_
return=0
incoming: _echo stupid=$stupidreturn_
stupid=97
与调试函数返回值关联的唯一“魔力”是:
0-成功2-子例程中的特殊行为(模拟返回)
其他非零-跳过下一个命令
因此,
97
的值在功能上似乎与1
的值等效,但它在脚本的正常流程中仍然不可用,因此它不会填充$?
请让我澄清一下:您向我展示了如何在调试陷阱中获得97。但是,我希望97可以在debugtrap之外通过$访问?阻止原始命令执行时。@spawn-gotcha。重写答案,让我知道它现在是否更好地回答了你的问题。谢谢你的重写。很抱歉,它仍然没有回答我想问的问题——正如您所说:“它仍然没有在脚本的正常流程中提供,因此它没有填充$?”。这就是我感兴趣的行为。为什么“它不是那样工作的”不能回答这个问题?我甚至提供了一个解决方案,使用一个全局变量。如果你所要求的是根本不可能的,那么答案就永远不会被接受吗?这当然是可能的,例如通过黑客攻击内存位置,$?直接使用类似的工具存储。我在上面的问题中引用了查尔斯·达菲的答案,这也意味着这并非不可能。这是否是解决问题的好办法是另一个问题。