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'm using bash as my main shell, but it's an open question and responses for shells others than bash are very welcome.

If I'm typing interactively

#original line 
#wget http://something.com && unzip something && mv -f something /home/poney/ 
#new line
wget http://something.com ; unzip something ; mv -f something /home/poney/

Does it make any difference in term of execution pile, order, memory, interpretation, permission compare to a script that contains those line:

#!/bin/bash
wget http://something.com
unzip something 
mv -f something /home/poney/

PS:

except the fact that executing a script is shorter than typing 3 command in a row obviously.

share|improve this question
1  
I'm not really convince about the duplicate because I'm also asking about pur scripting which is in my opinion different than interactive shell. –  Kiwy Apr 2 at 12:02
1  
    
@Kiwy But you did change the title completely. It is much more clear now. –  Bernhard Apr 2 at 17:10
add comment

3 Answers 3

up vote 17 down vote accepted

Yes, there is a big difference. && is short-circuiting, so the subsequent command would be executed only if the previous one returned with an exit code of 0.

Quoting from the manual:

expression1 && expression2

True if both expression1 and expression2 are true.

On the other hand, a script containing

expression1
expression2

would execute the second expression even if the first failed. (Unless you specified the script to exit on error by saying set -e.)


EDIT: Regarding your comment whether:

command1; command2

is the same as:

command1
command2

The answer is usually. Bash parses an entire statement block before evaluating any of it. A ; doesn't cause the previous command to be evaluated. If the previous command were to have an effect on how the subsequent one would be parsed, then you'd notice the difference.

Consider a file containing aliases, lets call it alias, with an entry:

alias f="echo foo"

Now consider a script containing:

shopt -s expand_aliases
source ./alias
f

and another one containing:

shopt -s expand_aliases; source ./alias; f

then you might think that both would produce the same output.

The answer is NO. The first one would produce foo but the second one would report:

... f: command not found

To clarify further, it's not expand_aliases that's causing the problem. The problem is due to the fact that a statement like:

alias f="echo foo"; f

would be parsed in one go. The shell doesn't really know what f is, this causes the parser to choke.

share|improve this answer
    
OK then my qeustion should have been with command ; command2; command3 –  Kiwy Apr 2 at 9:50
    
@Kiwy You mean ; instead of &&? –  devnull Apr 2 at 9:52
    
so indeed the context of execution make the execution of a script and an interactive script behave differently mainly because of bash variable ? –  Kiwy Apr 2 at 10:26
    
@Kiwy Environment variable? –  devnull Apr 2 at 10:28
1  
@terdon Bash parses an entire statement block before evaluating any of it. A ; doesn't cause the previous command to be evaluated. As such, the parser chokes on encountering an unknown command. –  devnull Apr 2 at 15:46
show 8 more comments

Yes, && is condition. Command behind will be started only if the previous one returns 0 (ends without an error). On the other hand your script hasn't this control so if eg. wget ends with error it will continue and try to unzip and move nothing..

Onliner for your script is:

wget http://something.com ; unzip something ; mv -f something /home/poney/
share|improve this answer
    
does the semi colon in this case are the same as the jumpline in my script ? –  Kiwy Apr 2 at 9:58
    
@Kiwy, yes it is. –  Graeme Apr 2 at 10:15
add comment

Another difference to the one mentioned is that your shell script runs in a separate shell, therefore any changes to the environment won't propagate out. For example, if you type in your interactive shell

test -f foo && file=foo || file=other

then your interactive shell will contain a variable file (which you can read with $file) containing foo if the file foo exists and is a regular file, and other otherwise. Now if you put the same in a shell script and call that from your interactive shell, then the variable file in your interactive shell will not be set (but of course inside your shell script it will be set, so you can use it in further commands therein).

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