在bash中使用heredoc之后使用&&

问题描述 投票:18回答:2

我有一个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多个命令。

bash heredoc
2个回答
34
投票

将命令链接在一行中

你可以把control operator &&放在你的EOFhere document字之后,你可以链接多个命令:

cat > file <<-EOF && echo -n "hello " && echo world

它将等待你的here-document,然后打印hello world。

Example

$ 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

Example

$ 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围绕一大块代码不是直接替代方案,您必须注意以下解释:

Surrounding dependant commands with set [-+]e

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

如您所见,如果您需要在包围的命令之后继续执行命令,则此解决方案不起作用。

Grouping Commands to the rescue

相反,您可以对包围的命令进行分组,以便按如下方式创建子shell:

echo first_command
false # it doesnt 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 doesnt stop the execution of the script
echo last_command

因此,如果您需要在链接命令之后执行其他操作并且想要使用the set builtin,请考虑上面的示例。

另请注意关于subshells的以下内容:

命令替换,用括号分组的命令和异步命令在子shell环境中调用,该shell环境是shell环境的副本,除了shell捕获的陷阱被重置为shell在调用时从其父级继承的值。作为管道的一部分调用的内置命令也在子shell环境中执行。对子shell环境所做的更改不会影响shell的执行环境。


3
投票

如果您使用&&运算符只是为了停止命令失败而不是继续,您可能希望用set -e包围代码块并用set + e关闭。这样你可以删除&&,你的代码很可能看起来更干净。

© www.soinside.com 2019 - 2024. All rights reserved.