我在多篇文章中读到,类似UNIX的shell中的分号(;
)等于换行。
但是,以下内容使我感到困惑,而且我也没有运气来搜索它。
我猜想这是外壳中do
的问题,但是“ bash分号”并不是最适合Google的搜索词组合。
下面是一个简单的for
语句。
for i in {1..10}
do
echo "hi"
echo "bye"
done
随着许多Stack Overflow大师的发布,每个换行符都可以用分号代替。
所以..我们有以下“相同”的声明。
for i in {1..10}; do; echo "hi"; echo "bye"; done
我们得到:
-bash: syntax error near unexpected token `;'
分号到底是什么?这仅仅是do
的一个独特问题吗?
答案 0 :(得分:5)
for name [ [in [words …] ] ; ] do commands; done
我们可以看到do
之后紧跟 commands
,因此在do
之后使用换行符不会代替分号,而是空格。
compound commands的说明也说
在大多数情况下,复合命令说明中的命令列表可能与一个命令的其余部分之间用一个或多个换行符分隔,并且可能会在换行符后用分号代替。
但是没有地方说您可以插入随机分号。 “每个换行符都可以用分号代替”只是一种笼统的说法,并不正确。
更多手动证据:在关于lists of commands的部分中,(强调我):
list
是由一个或多个运算符;
,&
,&&
或||
中的一个或多个管线组成的序列,并且可以选择由;
,&
或newline
之一终止。在这些列表运算符中,
&&
和||
具有相同的优先级,其次是;
和&
,具有相同的优先级。在
list
中可能会出现一个或多个换行符序列,以分隔命令,等同于分号。
因此,换行符等效于命令列表中的分号 。
答案 1 :(得分:5)
do
不是正义;在许多情况下,shell允许换行符,而不允许使用分号。
其中大多数(在引号中省略换行或分号的使用,它们总是彼此不同的):
在&&
或||
之后
some_command &&
some_other_command
在管道(|
)之后:
some_producer |
some_consumer
在in
语句中for
之前:
for x
in $(produce_values); do
尽管空命令是非法的,但Shell语法确实允许在for
命令中使用空值列表,因此for x in; do do_something; done
是合法的,因此用换行符而不是分号写的东西也是一样。
在in
语句中case
之前或之后;在关闭每个模式的)
和关闭每个案例的;;
之后:
case $x
in
pattern)
do_something ;;
esac
在关键字if
,then
,elif
,else
,while
或until
之后:
if
some_condition
then
do_something
else
do_something_else
fi
在{
或(
之后,打开复合命令或子外壳:
{
a_command
another_command
}
(
a_command
another_command
)
类似地,在$(
之后开始命令替换:
a=$(
echo hello
)
在bash中,这也适用于(
进程替换中的<(...)
。有关条件和算术替换的bash扩展中的处理方式,请参见下文。
函数定义中)
之后:
my_function()
{
do_something
}
在;
或&
之后终止命令:
do_something;
do_something_in_background &
(请注意,空命令是非法的,因此do_something; ;
将被拒绝。)
我从shell grammar in the Posix standard中获得了该列表。 Bash允许在其他地方使用换行符;写这个答案的时候我什么都没想到,但是@BenjaminW提醒我:
在带括号的数组文字中,无论是在数组分配中还是在数组声明中,换行符都被视为空格:
a+=(
first_thing
second_thing
)
local -A b=(
[x]="value of x"
[y]="value of y"
)
然后我想起了其他伪引用环境:
Bash还接受换行符作为算术表达式内的空格:
i=$((
i +
3 * j
))
if ((
i + 3 * j
>
9
))
在[[
样式的条件语句中]]
之后或[[
之前:
if
[[
$a -eq "done"
]]
then break
fi