我有一个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必须单独上线。&&
单独放在一条线上。不起作用,因为bash认为我正在尝试使用&&
作为命令。&&
重定向器之前放置>
。没有用,因为重定向器在逻辑上是&&
- ed。澄清:
在从heredoc生成配置文件的命令后面有很多(多行)命令,所以理想情况下我正在寻找一个允许我在heredoc之后放置以下命令的解决方案,这是自然的流程剧本。这是我宁愿不必在一行上内联20+命令。
答案 0 :(得分:34)
您可以将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之后放置以下命令,可以用花括号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
如果您要使用set [-+]e
而不是链式命令使用&&
,则必须注意围绕一块代码{{1 }}和set -e
不是直接替代方案,您必须注意以下说明:
set [-+]e
set +e
如您所见,如果您需要在包围的命令之后继续执行命令,则此解决方案无效。
相反,您可以对包围的命令进行分组,以便按如下方式创建子shell:
echo first_command
false # it doesnt 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
因此,如果您需要在链接命令后执行其他操作并且想要使用the set
builtin,请考虑上面的示例。
另请注意以下关于subshells:
的内容命令替换,用括号分组的命令和异步命令在shell shell环境中调用,该shell环境与shell环境重复,除了shell捕获的陷阱被重置为shell在调用时从其父级继承的值。作为管道的一部分调用的内置命令也在子shell环境中执行。对子shell环境所做的更改不会影响shell的执行环境。
答案 1 :(得分:3)
如果您正在使用&amp;&amp;运算符只是为了停止命令失败而不是继续,你可能希望用set -e包围代码块并用set + e关闭。这样你可以删除&amp;&amp;并且您的代码很可能看起来更干净。