Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
767 views
in Technique[技术] by (71.8m points)

unix - Why does bash -c "false; echo $?" print 0?

I'm building a script that tries to run some commands on a server (over SSH), and writes on the screen whether they were successful.

I noticed a strange behaviour for $?, namely not being 0 when the previous command failed.

Initially, I had:

ssh <user>@<server> <<EOF
    false
    if [ $? -ne 0 ]; then
        echo "It failed"
    else
        echo "It worked"
    fi
EOF

If I copy and paste the script inside <<EOF and EOF, it prints It failed. If I run it with the ssh part, it prints It worked. To simplify, I then tried:

ssh <user>@<server> <<EOF
    false
    echo $?
EOF

Same thing happened. If I copy-paste or type the commands inside, it prints 1, but if I run all of it (including the ssh), it prints 0.

The same error happens if I directly use bash this way

bash <<EOF
    false
    echo $?
EOF

or

bash -c "false; echo $?"

Why does this happen? How can I check if the previous command failed in this context?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This is due to variable expansion. When you write bash -c "false; echo $?" the variable is expanded before the commands are ran. So your command is exactly like bash -c "false; echo 0;" if your previous command was successful.

To have the right result try bash -c 'false; echo $?'. This prevents variable expansion, it will be expanded when interpreted.

For the here document version do:

bash << 'EOF'
false
echo $?
'EOF'

In this case you need to quote the delimiter of the here document. But beware that the syntax you must use is the syntax for the shell you use to type the command. In the example, I was in tcsh , and it requires to use the exact same opening and closing delimiter. Under bash, the closing delimiter must be the opening one after quote removal.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...