Bash调试陷阱使用extdebug保留了自定义退出值

时间:2018-09-07 14:18:23

标签: bash

我正在使用bash的调试陷阱来操纵命令并在调试陷阱功能内执行它们,同时阻止执行原始命令。

private string UseTheMethod(SecureString secret)
{
    var comObject = new TheComObject();
    var comObjectDispatcher = (ITheComObjectDispatcher)comObject;
    var secretPtr = Marshal.SecureStringToBSTR(secret);
    try
    {
        return comObjectDispatcher.TheMethod(secretPtr);
    }
    finally
    {
        Marshal.ZeroFreeBSTR(secretPtr);
    }
}

通过从陷阱返回1来阻止执行命令。但是,我希望将shopt -s extdebug 设置为命令的退出状态。而是$?始终为零。请查看以下代码:

$?
我的愚蠢自定义命令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 是(我想要的)时,未执行

echo hi。 允许使用下一个命令(exit 97),因为该陷阱返回0。在这种情况下,我希望echo $?为97。有什么办法吗?

In another question查尔斯·达菲回答

  

但是请不要担心:除非您的陷阱返回的非零值(因此中止了它们之前运行的命令),否则就很容易解决:

所以,我想在这种情况下并不是那么容易-至少我还没有找到方法。有人吗?

1 个答案:

答案 0 :(得分:1)

所以……您的“愚蠢的自定义命令”是在子外壳中执行的,但是按照您的说法,您的函数有两个可能的返回值,分别由return 0return 1生成。这些返回值用于指导脚本命令的执行,在程序执行过程中不可用。

也就是说,您可以将嵌入式命令的返回值记录在另一个变量中。例如:

#!/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的值,但是在脚本的正常流程中 still 仍然不可用,并且因此它不会填充$?