我有一个bash脚本,我使用&&将其命令链接在一起,因为如果各个步骤失败,我希望脚本停止。

步骤之一是基于heredoc创建配置文件:

some_command &&
some_command &&
some_command &&
some_command &&
some_command &&
some_command &&
cat > ./my-conf.yml <<-EOF
host: myhost.example.com
... blah blah ...
EOF
... lots more commands ...

如何在&&链中包含此命令?我试过了:
  • 在EOF之后立即放置&&。无效,因为EOF必须自己排成一行。
  • 在EOF之后,将&&自己放在一行上。不起作用,因为bash认为我正在尝试使用&&作为命令。
  • &&重定向器之前放置>。无效,因为重定向器在逻辑上是&& -ed命令的一部分。

  • 声明:

    从Heredoc生成配置文件的命令后面有很多(多行)命令,因此理想情况下,我正在寻找一种解决方案,该解决方案允许我将以下命令放置在Heredoc之后,这是脚本的自然流程。那就是我希望不必在一行上内联20多个命令。

    最佳答案

    单行链接命令
    您可以将control operator &&放在here document中的EOF词之后,并且可以链接多个命令:

    cat > file <<-EOF && echo -n "hello " && echo world
    
    它将等待您的here-document,然后打印 hello world
    $ cat > file <<-EOF && echo -n "hello " && echo world
    > a
    > b
    > EOF
    hello world
    
    $ cat file
    a
    b
    

    heredoc分隔符后的链接命令
    现在,如果要在heredoc后面放置以下命令,则可以将其在花括号中添加group,然后继续按以下方式链接命令:
    echo -n "hello " && { cat > file <<-EOF
    a
    b
    EOF
    } && echo world
    
    $ echo -n "hello " && { cat > file <<-EOF
    > a
    > b
    > EOF
    > } && echo world
    hello world
    
    $ cat file
    a
    b
    

    使用the set built in
    如果要使用set [-+]e代替&&的链接命令,则必须注意,用set -eset +e围绕代码块不是直接的选择,并且必须注意以下事项:
    set [-+]e 包围相关命令
    echo first_command
    false # it doesn't stop the execution of the script
    
    # surrounded commands
    set -e
    echo successful_command_a
    false # here stops the execution of the script
    echo successful_command_b
    set +e
    
    # this command is never reached
    echo last_command
    
    如您所见,如果您需要在包围的命令之后继续执行命令,则此解决方案无效。
    Grouping Commands进行救援
    相反,您可以对包围的命令进行分组,以如下所示创建子 shell :
    echo first_command
    false # it doesn't stop the execution of the script
    
    # surrounded commands executed in a subshell
    (
    set -e
    echo successful_command_a
    false # here stops the execution of the group
    echo successful_command_b
    set +e # actually, this is not needed here
    )
    
    # the script is alive here
    false # it doesn't stop the execution of the script
    echo last_command
    
    因此,如果您需要在链接命令之后执行其他操作,并且想要使用the set builtin,请考虑上面的示例。
    另请注意有关subshells的以下内容:

    关于bash - 在bash中的Heredoc之后使用&&,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27301806/

    10-16 08:02