Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash分号等于换行符不完全正确?_Bash_Shell - Fatal编程技术网

Bash分号等于换行符不完全正确?

Bash分号等于换行符不完全正确?,bash,shell,Bash,Shell,我在多篇文章中读到,类UNIX shell中的分号(;)等于一个新行。 然而,下面的内容让我很困惑,我也没有在谷歌上找到它 我猜这是shell中的do的一个问题,但是“bash分号do”并不是谷歌最友好的搜索词组合 下面是一个简单的for语句 for i in {1..10} do echo "hi" echo "bye" done for i in {1..10}; do; echo "hi"; echo "bye"; done 正如许多堆栈溢出专家所发布的,每一个换行符都可以用分号代替

我在多篇文章中读到,类UNIX shell中的分号(
)等于一个新行。
然而,下面的内容让我很困惑,我也没有在谷歌上找到它

我猜这是shell中的
do
的一个问题,但是“bash分号do”并不是谷歌最友好的搜索词组合

下面是一个简单的
for
语句

for i in {1..10}
do
echo "hi"
echo "bye"
done
for i in {1..10}; do; echo "hi"; echo "bye"; done
正如许多堆栈溢出专家所发布的,每一个换行符都可以用分号代替

所以。。我们有以下“相同”的说法

for i in {1..10}
do
echo "hi"
echo "bye"
done
for i in {1..10}; do; echo "hi"; echo "bye"; done
我们得到:

-bash: syntax error near unexpected token `;'
分号到底是什么?这只是一个独特的问题吗

用于名称[[in[words…]];]do命令;完成
我们可以看到,
do
后面紧跟着
命令
,因此在
do
后面使用换行符并不能替换分号,而是替换空格

描述也说

在大多数情况下,复合命令描述中的命令列表可以用一个或多个换行符与命令的其余部分分开,并且后面可以用换行符代替分号

但它并没有说可以插入随机分号。“每一个换行符都可以用分号代替”这句话太笼统了,不正确

更多的手工证据:在关于的部分,它说(强调我的):

列表是由一个操作员
分隔的一个或多个管道的序列
|
,并可选择由
之一终止
,或
换行符

在这些列表运算符中,
&&
|
具有同等的优先级,然后是
&
,它们具有相同的优先级

一个或多个换行符的序列可能出现在
列表中,用于分隔命令,相当于分号。

因此,换行符相当于命令列表中的分号。

它不仅仅与
do
有关;在许多上下文中,shell允许换行,而不允许分号

以下是它们中的大多数(不包括引号中的换行符或分号,它们总是彼此不同):

  • &&
    |

    some_command &&
    some_other_command
    
  • 管道后(
    |
    ):

  • 中的
    之前,在
    for语句的
    中:

    for x
    in $(produce_values); do
    
    尽管空命令是非法的,但是shell语法允许
    中的空值列表用于
    命令,因此
    用于x in;做点什么;完成
    是合法的,同样的事情用换行符而不是分号来写也是合法的

  • 案例
    语句中的
    之前或之后;也是在每个图案的
    关闭之后关闭每个案例:

    case $x
    in
    pattern)
      do_something ;;
    esac
    
  • 在关键字
    如果
    然后
    elif
    其他
    while
    之后,直到

    if
      some_condition
    then
      do_something
    else
      do_something_else
    fi
    
  • 在打开复合命令或子shell的
    {
    之后:

    {
       a_command
       another_command
    }
    
    (
       a_command
       another_command
    )
    
    类似地,在启动命令替换的
    $(
    之后:

    a=$(
      echo hello
    )
    

    在bash中,这也适用于
    进程替换:
    谢谢。我没想到换行符在某些上下文中可以替换分号和空格。但这仍然很让人困惑。这不像你可以做
    my_script.shparams
    。我想换行符\n有时可以替换为空格或分号,但有时不能?@gyuhyonlee I's如果说换行符和空格可互换的“经验”准则是“当按下enter键后显示辅助提示(通常是
    )时”,即shell希望您的命令继续。好吧,这对于
    do
    then
    (来自if..then)来说几乎是一个独特的问题。我想不出另外一种情况,用
    替换换行符会失败(并且在空格很重要的情况下,herdeocs是它们自己的特殊功能,所以不算数)。不过,我已经准备好被更正!=)另外对于Bash:在数组声明中,
    arr=(\nel1\nel2\n)
    是可以的,
    arr=(;el1;el2;)
    不是。@benjaminW:是的,数组声明中的括号是一种引用。我忘记了这一点;谢谢。尤其是关联数组(如您的示例所示),使用换行符可以在可读性上提高一个数量级,IMO。感谢您的善意解释。手册页真的很折磨人,我不知道如何搜索这些内容。我想我最好习惯手册页。@Gyuhyonlee如果您阅读了像强烈推荐的最佳实践指南,您可以遵循synt在例子中使用斧头和风格,避免大多数问题;你的问题已经深入到了本质。这当然不是一件坏事,但在开始时可能会降低积极性。
    my_function()
    {
      do_something
    }
    
    do_something;
    do_something_in_background &
    
    a+=(
      first_thing
      second_thing
    )
    
    local -A b=(
      [x]="value of x"
      [y]="value of y"
    )
    
    i=$((
       i + 
         3 * j
    ))
    
    if ((
      i + 3 * j
      >
      9
    ))
    
    if
    [[
          $a -eq "done"
    ]]    
    then break
    fi