使用 ; 和有什么区别?并执行脚本

使用 ; 和有什么区别?并执行脚本

我将其用作bash我的主要 shell,但这是一个开放的问题,对于其他 shell 的回答也bash非常受欢迎。

如果我以交互方式打字

#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/

与包含这些行的脚本相比,它在执行堆、顺序、内存、解释、权限方面有什么区别吗:

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

附:

除了执行脚本显然比连续输入 3 个命令要短这一事实之外。

答案1

是的,有很大的不同。 &&短路,因此仅当前一个命令返回退出代码为 时,才会执行后续命令0

引用自手动的:

表达式1 && 表达式2

True if both expression1 and expression2 are true.

另一方面,一个脚本包含

expression1
expression2

即使第一个表达式失败也会执行第二个表达式。 (除非您通过说指定脚本在出错时退出set -e。)


编辑:关于您的评论是否:

command1; command2

是相同的:

command1
command2

答案是通常。 Bash 在评估任何一个语句块之前都会解析整个语句块。 A ;不会导致评估前一个命令。如果前一个命令影响后一个命令的解析方式,那么您会注意到其中的差异。

考虑一个包含别名的文件,我们称之为alias,并带有一个条目:

alias f="echo foo"

现在考虑一个包含以下内容的脚本:

shopt -s expand_aliases
source ./alias
f

另一个包含:

shopt -s expand_aliases; source ./alias; f

那么您可能会认为两者都会产生相同的输出。

答案是不。第一个会产生,foo但第二个会报告:

... f: command not found

进一步澄清一下,这并不是expand_aliases造成问题的原因。问题是由于这样的语句:

alias f="echo foo"; f

将会解析的一气呵成。 shell 并不真正知道f是什么,这会导致解析器卡住。

答案2

是的,&&是条件。仅当前一个命令返回0(结束且没有错误)时,后面的命令才会启动。另一方面,您的脚本没有此控件,因此如果例如。 wget 以错误结束,它将继续并尝试解压缩并移动任何内容。

您的脚本的在线版本是:

wget http://something.com ; unzip something ; mv -f something /home/poney/

答案3

与上述的另一个区别是您的 shell 脚本在单独的 shell 中运行,因此对环境的任何更改都不会传播出去。例如,如果您在交互式 shell 中输入

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

那么您的交互式 shell 将包含一个变量file(您可以使用 读取$file),其中包含foo文件 foo 是否存在并且是常规文件,other否则。现在,如果您将相同的内容放入 shell 脚本中并从交互式 shell 中调用它,则file交互式 shell 中的变量将不会被设置(但当然在 shell 脚本中它将被设置,因此您可以在进一步的命令中使用它)其中)。

相关内容