如何为在bash中不退出的gpg命令返回退出值以验证错误的密码短语?

如何为在bash中不退出的gpg命令返回退出值以验证错误的密码短语?,bash,gnupg,exit-code,Bash,Gnupg,Exit Code,在GPG中,没有适当的文档说明如何通过bash代码检查有效的密码短语,因此,这是一种黑客行为。基于以下示例代码,用于检查GPG代理中缓存的GPG密码是否有效: #!/bin/bash KEY_ID=YOUR_KEY_ID echo "1234" | gpg -q --batch --status-fd 1 --sign --local-user $KEY_ID --passphrase-fd 0 --output /dev/null return_code=$? if [ &

在GPG中,没有适当的文档说明如何通过bash代码检查有效的密码短语,因此,这是一种黑客行为。基于以下示例代码,用于检查GPG代理中缓存的GPG密码是否有效:

#!/bin/bash
KEY_ID=YOUR_KEY_ID
echo "1234" | gpg -q --batch --status-fd 1 --sign --local-user $KEY_ID --passphrase-fd 0 --output /dev/null
return_code=$?
if [ "$return_code" = 0 ]; then
 echo "Valid passphrase has been set in gpg-agent"
   else
 echo "Invalid passphrase or no passphrase is set in gpg-agent"
fi
如果设置了有效的密码短语,并且在运行此bash脚本时,返回值为0。这是正确的

但是

如果未设置密码短语或无效密码短语,我可以看到该命令正在等待一些未知的输入或进程,并且它不会退出(在使用CTRL+C终止之前闪烁光标)。但这是一个很好的信号,表明提供了无效的密码短语

我的问题是,如果提供了无效的密码短语,如何强制命令退出并获得返回值1,以便正确使用if-else条件

从代码中重现问题的注释和信息(这不是问题): 要设置gpg密码,有两种方法:

  • gpg——导出密钥-a
    (这可以验证密码短语)或

  • 如果bash中没有提示:
    /usr/libexec/gpg预设密码短语-c$KEY\u GRIP,您可以尝试以下操作:

    echo "1234" | gpg -q --batch --status-fd 1 --sign --local-user <KEY_ID> --passphrase-fd 0 --output /dev/null ||
    {
        echo "Invalid passphrase or no passphrase is set in gpg-agent"
        exit
    }
    echo "Valid passphrase has been set in gpg-agent"
    
    echo“1234”| gpg-q--batch--status fd 1--sign--local user--passphrase fd 0--output/dev/null||
    {
    echo“gpg代理中的密码短语无效或未设置密码短语”
    出口
    }
    echo“已在gpg代理中设置有效的密码短语”
    

    我不确定这是否可以处理等待输入的情况。

    您可以尝试以下方法:

    echo "1234" | gpg -q --batch --status-fd 1 --sign --local-user <KEY_ID> --passphrase-fd 0 --output /dev/null ||
    {
        echo "Invalid passphrase or no passphrase is set in gpg-agent"
        exit
    }
    echo "Valid passphrase has been set in gpg-agent"
    
    echo“1234”| gpg-q--batch--status fd 1--sign--local user--passphrase fd 0--output/dev/null||
    {
    echo“gpg代理中的密码短语无效或未设置密码短语”
    出口
    }
    echo“已在gpg代理中设置有效的密码短语”
    
    我不确定这是否可以处理等待输入的情况。

    如果可以的话, 您可以启动另一个脚本来计算此脚本的执行时间。如果实际脚本退出,则输入正确的密码;否则,如果设置的时间达到,则杀死脚本的PID,脚本结束。

    如果可以的话,
    您可以启动另一个脚本来计算此脚本的执行时间。如果实际脚本退出,则输入正确的密码;否则,如果设置的时间达到,则终止脚本的PID,脚本结束。

    我已找到此问题的答案。由于错误,返回代码未正确输出。我只需要修改代码,这样它就不会使用默认的pin输入密码提示。使用pin输入密码短语可能会导致返回代码在基于此相关错误的随机时间被卡住()。简言之,返回代码在随机时间被卡住,但可以使用以下选项解决此问题:

    --pinentry模式=环回

    因此,上面的选项是禁用密码短语的pin输入提示,我们可以使用
    gpg preset passphrase
    实用程序在终端中设置密码短语。因此,使用此方法可以获得正确的返回代码

    我发现这个帖子讨论了如何在gpg代理中禁用pin输入,例如:

    因此,这是验证密码短语时使用正确返回码的工作代码:

    #!/bin/bash
    gpg-agent --daemon
    KEY_ID=ABC12321SS
    GPG_PRESET_PASS="/usr/libexec/gpg-preset-passphrase" # This utility came with gpg
    KEY_GRIP=$(gpg --with-keygrip --list-secret-keys "$KEY_ID" | grep -Pom1 '^ *Keygrip += +\K.*') # Get they key grip
    # Ask passphrase
    read -s -p "Enter a passphrase to cache into a running gpg-agent: " PASSPHRASE; echo
    # Cache RAW passphrase here. RAW passphrase means un-validated passphrase. Passphrase can be valid or invalid cached in gpg-agent.
    $GPG_PRESET_PASS -c $KEY_GRIP <<< $PASSPHRASE 
    # AND NOW WE check if a RAW passphrase is cached:
    RET_VAL=$?
    if [ $RET_VAL = 0 ]; then
            echo "Un-validated (RAW) passphrase is cached"
            # This is the part that I must use --pinentry-mode=loopback, so I will get correct return code
            echo "Now validating a RAW cached passphrase from gpg-agent ..."
            test=$(echo "1234" | gpg -q --pinentry-mode=loopback --status-fd 1 --sign --local-user "$KEY_ID" --passphrase-fd 0 > /dev/null)
            RET_VAL=$?
            if [ $RET_VAL = 0 ]; then
                    echo "Passphrase is valid"
            else
                    echo "Passphrase is invalid"
                    # Can clear the passphrase and ask again for RAW passphrase
            fi
    
    else
            echo "Error when trying to cache RAW passphrase"
            exit 1
            # Run again the script to cache RAW passphrase
    fi
    
    #/bin/bash
    gpg代理——守护进程
    密钥ID=ABC12321SS
    GPG_PRESET_PASS=“/usr/libexec/GPG PRESET passphrase”#此实用程序随GPG一起提供
    KEY_GRIP=$(gpg——带keygrip——列出密钥“$KEY_ID”| grep-Pom1'^*keygrip++=+\K.*)#获取密钥GRIP
    #询问密码短语
    read-s-p“输入要缓存到正在运行的gpg代理中的密码短语:”密码短语;回声
    #在此处缓存原始密码短语。原始密码短语指未经验证的密码短语。密码短语可以在gpg代理中缓存为有效或无效。
    
    $GPG\U PRESET\U PASS-c$KEY\U GRIP我找到了这个问题的答案。由于错误,返回代码未正确输出。我只需要修改代码,这样它就不会使用默认的pin输入密码提示。使用pin输入密码短语可能会导致返回代码在基于此相关错误的随机时间被卡住()。简言之,返回代码在随机时间被卡住,但可以使用以下选项解决此问题:

    --pinentry模式=环回

    因此,上面的选项是禁用密码短语的pin输入提示,我们可以使用
    gpg preset passphrase
    实用程序在终端中设置密码短语。因此,使用此方法可以获得正确的返回代码

    我发现这个帖子讨论了如何在gpg代理中禁用pin输入,例如:

    因此,这是验证密码短语时使用正确返回码的工作代码:

    #!/bin/bash
    gpg-agent --daemon
    KEY_ID=ABC12321SS
    GPG_PRESET_PASS="/usr/libexec/gpg-preset-passphrase" # This utility came with gpg
    KEY_GRIP=$(gpg --with-keygrip --list-secret-keys "$KEY_ID" | grep -Pom1 '^ *Keygrip += +\K.*') # Get they key grip
    # Ask passphrase
    read -s -p "Enter a passphrase to cache into a running gpg-agent: " PASSPHRASE; echo
    # Cache RAW passphrase here. RAW passphrase means un-validated passphrase. Passphrase can be valid or invalid cached in gpg-agent.
    $GPG_PRESET_PASS -c $KEY_GRIP <<< $PASSPHRASE 
    # AND NOW WE check if a RAW passphrase is cached:
    RET_VAL=$?
    if [ $RET_VAL = 0 ]; then
            echo "Un-validated (RAW) passphrase is cached"
            # This is the part that I must use --pinentry-mode=loopback, so I will get correct return code
            echo "Now validating a RAW cached passphrase from gpg-agent ..."
            test=$(echo "1234" | gpg -q --pinentry-mode=loopback --status-fd 1 --sign --local-user "$KEY_ID" --passphrase-fd 0 > /dev/null)
            RET_VAL=$?
            if [ $RET_VAL = 0 ]; then
                    echo "Passphrase is valid"
            else
                    echo "Passphrase is invalid"
                    # Can clear the passphrase and ask again for RAW passphrase
            fi
    
    else
            echo "Error when trying to cache RAW passphrase"
            exit 1
            # Run again the script to cache RAW passphrase
    fi
    
    #/bin/bash
    gpg代理——守护进程
    密钥ID=ABC12321SS
    GPG_PRESET_PASS=“/usr/libexec/GPG PRESET passphrase”#此实用程序随GPG一起提供
    KEY_GRIP=$(gpg——带keygrip——列出密钥“$KEY_ID”| grep-Pom1'^*keygrip++=+\K.*)#获取密钥GRIP
    #询问密码短语
    read-s-p“输入要缓存到正在运行的gpg代理中的密码短语:”密码短语;回声
    #在此处缓存原始密码短语。原始密码短语指未经验证的密码短语。密码短语可以在gpg代理中缓存为有效或无效。
    
    $GPG\U预设\U通过-c$KEY\U抓地力错误
    1
    是一个错误应该得到的,而
    0
    是成功应该得到的;正如标准UNIX退出状态值是如何定义的一样。。。如果
    gpg
    没有将来自密码短语FD的EOF视为退出条件,我建议将其作为一个bug提交给它的作者——或者按照我所做的做,然后切换到一个编写更好的OpenPGP实现(我使用这个实现)。不过,仅对标题而言:不退出的命令没有返回值。如果您想强制它退出,请考虑在 TimeOuts< /C> >或某些等价的情况下运行它。提供了一种到达目的地的方法。回到这里,重新审视你正在尝试做的事情。。。您正在尝试确定代理是否已加载密钥?你知道你可以直接查询代理,对吗<代码>gpg connect ag