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.

Ì want to execute a Bash command, followed by two actions if and only if the test returns an error. I would prefer to solve this task as a one-liner in Bash.

Here are the two forms I have tried:

ssh user@1.2.3.4 "ls /home/somefile" || echo "File does not exist" && exit 1
ssh user@1.2.3.4 "ls /home/somefile" || echo "File does not exist"; exit 1

The meaning is as follows: I want to test the existance of a file on a remote machine (or whatever, just an example), and in the case the first command returns an error, then - and only then- the two following commands (echo /exit) should be executed. The examples above execute the exit 1 statement independent of the return value of the ssh command.

How to rewrite this line, so the echo and the exit commands are only executed if the first (ssh) command fails?

share|improve this question
1  
You do this as ssh user@1.2.3.4 "ls /home/somefile" || (echo "File does not exist"; exit 1) I think. –  galegosimpatico Jan 27 at 16:22
    
Perfect- I tried exactly this and got an error. Now it works...? –  Alex Jan 27 at 16:23
add comment

1 Answer

up vote 12 down vote accepted
ssh user@1.2.3.4 "ls /home/somefile" || { echo "File does not exist"; exit 1; }

This is called a compound command. From man bash:

   Compound Commands
       A compound command is one of the following:

       (list) list  is  executed in a subshell environment (see COMMAND EXECU‐
              TION ENVIRONMENT below).  Variable assignments and builtin  com‐
              mands  that  affect  the  shell's  environment  do not remain in
              effect after the command completes.  The return  status  is  the
              exit status of list.

       { list; }
              list  is simply executed in the current shell environment.  list
              must be terminated with a newline or semicolon.  This  is  known
              as  a  group  command.   The return status is the exit status of
              list.  Note that unlike the metacharacters ( and ), { and }  are
              reserved words and must occur where a reserved word is permitted
              to be recognized.  Since they do not cause a  word  break,  they
              must  be  separated  from  list  by  whitespace or another shell
              metacharacter.

The () syntax probably wouldn't work in your situation because the commands would be executed in a subshell, and then the exit would just close the subshell.

EDIT: to explain the difference between the parentheses () and the curly braces {}:

The parentheses cause the contained commands to be executed in a subshell. That means that another shell process is spawned which evaluates the commands, and the exit in OP's question would kill this subshell.

The curly braces instead cause the commands to be evaluated in the current shell. Now the exit kills the current shell, which would be for example preferable if you use this line a shell script.

share|improve this answer
    
What is the difference between using round and the other brackets? –  Alex Jan 27 at 16:24
    
@Alex what it says in the answer, the first is executed in a separate subshell while the second is run in the same shell you're in. –  terdon Jan 27 at 16:26
add comment

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.