6

I want to execute two commands one after another via SSH. I don't have an interactive shell. The second command should only execute if the first one succeeds, but the line is inside a script, so I'd like some user-friendly feedback if the second command fails to execute this way. After that, the rest of the script should continue executing, so exit, etc. is not an option here.

I know I can use the boolean operator &&, e.g. foo && bar to prevent bar from executing if foo fails, and bar || baz to execute baz only on bar's failure. However I am a little confused as to how these work in conjunction with each other.

To sum it up:

(Executed via SSH without an interactive shell)

  1. Execute foo
  2. Execute bar ONLY if foo succeeds
  3. Execute baz ONLY if foo fails and prevents the execution of bar

ssh user@host "foo && bar || baz"

Is this a correct way to do what I just described?

  • I'm not quite sure what you're asking. Are you asking how to do this? How it works on a theoretical level? If your conclusion is correct? – bahamat Jul 14 '13 at 18:49
12

Using your example foo && bar || baz will execute baz if bar or foo fails. Based on your description, this not what you want. You can accomplish your goal using an if statement:

if foo; then
    bar
else
    baz
fi

Or if you want it on one line:

if foo; then bar; else baz; fi
  • Actually printing an error if either of the two fails could be better, now that I think of it - thanks for noticing. The problem I see with the if statement is that the commands are supposed to be passed through SSH and I need it to be a single line. Can this be written as ssh user@host "if foo; then bar else baz fi"? – rld. Jul 14 '13 at 18:56
  • @R3load. To put it on one line, you need to replace the newlines with ;. I put it on multiple lines for clarity. – jordanm Jul 14 '13 at 19:00
  • I should've tried it myself before commenting, figured it out this way too, thanks though. Accepting your answer, that's just what I need. – rld. Jul 14 '13 at 19:04
3

The full syntax of shell script is available to you in the ssh command. (The commands are executed by the remote account's default shell; we are assuming here that it is sh-compatible.)

Compund commands have to be quoted. While your use of double quotes is correct, I would recommend single quotes, since they protect all shell special characters; this can be important if you want to use nontrivial shell constructs in your remote commands.

With that out of the way, here is one way to do what you want:

ssh user@host 'foo && bar || { echo foo failed >&2; baz; }'

You can also use arbitrarily complex conditionals:

ssh user@host '
    if foo; then
         bar
    else
        echo foo failed >&2
        baz
    fi'

(Yes, that's a single, multi-line string inside single quotes.)

  • One small gotcha: That last semi-colon after 'baz' is crucial. It's necessary, even if there's only one command inside the curly braces. – ishmael Dec 15 '14 at 21:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.