15

Today I opened gnome-terminal and I wrote

ls && sleep 4 && gnome-terminal

to open another terminal after the completion of ls command and waiting for 4 seconds.
So it successfully opened a new terminal after previous commands completely ran (including sleep 4).

After that, next time I typed a new command

ls -lR && sleep 4 && gnome-terminal

The command ls -lR completed after 3 seconds, but after that none of the commands sleep 4 and gnome-terminal ran successfully.

What is the problem?

0

2 Answers 2

29

&& means to run it if the previous command was successful. In Unix that generally means exit status 0.

$ ls barfoofba && echo "This will not be echo'd"
ls: cannot access 'barfoofba': No such file or directory
$ ls bar && echo "This will be echo'd"  
This will be echo'd

In the first instance, ls did not succeed, so it exited with a non-zero exit status, and bash did not run the second command.

In the second example, I ls'd a existing file, so ls exited with 0 as exit status, and the command was executed.

If you want to run commands unconditionally, e.g. not dependent on the result of the first, you may separate them with ; like this

 command1; command2; command3 

and so forth.

Thus you may do

ls -lR ; sleep 4 ; gnome-terminal

In addition to && and ; you have || which is the opposite of &&: Only run the command if the previous command failed with a non-zero exit status. If the first command succeeds, the next will not be executed. If it fails, the next will be executed.

So in short:

  • &&: Run if preceding command exited with 0
  • ;: Run unconditionally
  • ||: Run if preceding command exited with a non-zero exit status.
  • &: Run both commands in paralell, the first in background and second in foreground.
9
  • 7
    I think of it like 0 means SUCCESS which is like true. Jan 29, 2019 at 0:00
  • 4
    @KodosJohnson In the C world, 0 means success because non-zero means an error, and there could be hundreds of error codes (see error.h). Happy return codes are all alike... Jan 29, 2019 at 2:48
  • 4
    @AbhishekKamal No, I can't try on my machine. ls -lR should work, but it might fail if it for instance hits one directory it doesn't have permissions to look in. For instance will ls -lR / always fail...
    – vidarlo
    Jan 29, 2019 at 5:53
  • 2
    @JonBentley The "echo" in "echo'd" is the name of a command, not an English verb, even if it happens to be spelled the same, so it's somewhat open to question how it should be conjugated. This is more obvious if you pick other commands: what would the past tense of ls be, for instance?
    – IMSoP
    Jan 29, 2019 at 15:29
  • 2
    @chrylis: No, the point is exactly that "0 for true" is not how it is "in the C world". In the C programming language, conditionals (and the logical operators) consider 0 to be false and everything else to be true. The convention for process exit codes in the shell is exactly the opposite. -- Even though both C and the shell are both parts of a larger Unix tradition. Jan 29, 2019 at 16:55
12

The command ls -lR exited with an exit-status different than zero, so the following commands have not been executed. Most probably ls was unable to open a subdirectory. It didn't happen in your first command because you didn't use the -R-option.

From man bash:

        command1 && command2
       command2  is  executed if, and only if, command1 returns an exit status
       of zero.

From man ls:

Exit status:
       0      if OK,
       1      if minor problems (e.g., cannot access subdirectory)
       2      if serious trouble (e.g., cannot access command-line argument).
2
  • Thanks @mook765, Your answer is perfect according to my question.. I cleared my confusion Jan 29, 2019 at 1:50
  • According to your answer, when i run ls -lR && sleep 4 && gnome-terminal with sudo, it successfully runs. Jan 29, 2019 at 1:52

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