为什么bash -c"false; echo $?" 打印0?

Vla*_*d V 3 unix bash

我正在构建一个尝试在服务器上运行某些命令的脚本(通过SSH),并在屏幕上写入它们是否成功.

我注意到一个奇怪的行为$?,即不是0在前一个命令失败时.

最初,我有:

ssh <user>@<server> <<EOF
    false
    if [ $? -ne 0 ]; then
        echo "It failed"
    else
        echo "It worked"
    fi
EOF
Run Code Online (Sandbox Code Playgroud)

如果我复制并粘贴里面的脚本<<EOFEOF,它打印It failed.如果我用ssh零件运行它,它会打印出来It worked.为了简化,我尝试了:

ssh <user>@<server> <<EOF
    false
    echo $?
EOF
Run Code Online (Sandbox Code Playgroud)

同样的事发生了.如果我复制粘贴或在里面输入命令,它会打印1,但是如果我运行它(包括ssh),它就会打印出来0.

如果我以这种方式直接使用bash,则会发生同样的错误

bash <<EOF
    false
    echo $?
EOF
Run Code Online (Sandbox Code Playgroud)

要么

bash -c "false; echo $?"
Run Code Online (Sandbox Code Playgroud)

为什么会这样?如何在此上下文中检查上一个命令是否失败?

Jea*_*nès 9

这是由于可变扩展.在编写bash -c "false; echo $?"变量时,在运行命令之前展开变量.所以你的命令就像bash -c "false; echo 0;"你以前的命令成功一样.

要获得正确的结果,请尝试bash -c 'false; echo $?'.这可以防止变量扩展,在解释时会扩展.

对于这里的文档版本做:

bash << 'EOF'
false
echo $?
'EOF'
Run Code Online (Sandbox Code Playgroud)

在这种情况下,您需要引用此文档的分隔符.但要注意,必须使用的语法是用于键入命令的shell的语法.在示例中,我进入了tcsh,它需要使用完全相同的开始和结束分隔符.在下面bash,结束分隔符必须是引用删除后的开头分隔符.

  • 我想这还是错的.你必须引用第一个`EOF`. (2认同)