Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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?

share|improve this question
    
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

2 Answers 2

up vote 6 down vote accepted

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
share|improve this answer
    
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

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.)

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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