Using && after a heredoc in bash
Chaining commands in a single line
You can put the control operator &&
right after the EOF
word in your here document and you can chain more than one command:
cat > file <<-EOF && echo -n "hello " && echo world
It will wait for your here-document and then will print hello world.
Example
$ cat > file <<-EOF && echo -n "hello " && echo world> a> b> EOFhello world$ cat fileab
Chaining commands after the heredoc delimiter
Now, if you want to place the following commands after the heredoc, you can group it in curly braces and continue chaining commands as follows:
echo -n "hello " && { cat > file <<-EOFabEOF} && echo world
Example
$ echo -n "hello " && { cat > file <<-EOF> a> b> EOF> } && echo worldhello world$ cat fileab
Using the set built in
If you're going to use set [-+]e
instead of chained commands with &&
, you must notice that surrounding a chunk of code with set -e
and set +e
is not a direct alternative and you must take care of the following:
Surrounding dependent commands with set [-+]e
echo first_commandfalse # it doesn't stop the execution of the script# surrounded commandsset -eecho successful_command_afalse # here stops the execution of the scriptecho successful_command_bset +e# this command is never reachedecho last_command
As you can see, if you need to go on executing commands after the surrounded commands, this solution doesn't work.
Grouping Commands to the rescue
Instead, you can group the surrounded commands in order to create a subshell as follows:
echo first_commandfalse # it doesn't stop the execution of the script# surrounded commands executed in a subshell(set -eecho successful_command_afalse # here stops the execution of the groupecho successful_command_bset +e # actually, this is not needed here)# the script is alive herefalse # it doesn't stop the execution of the scriptecho last_command
So, if you need to execute something else after your chained commands and you want to use the set
builtin, consider the examples above.
Also notice the following about subshells:
Command substitution, commands grouped with parentheses, and asynchronous commands are invoked in a subshell environment that is a duplicate of the shell environment, except that traps caught by the shell are reset to the values that the shell inherited from its parent at invocation. Builtin commands that are invoked as part of a pipeline are also executed in a subshell environment. Changes made to the subshell environment cannot affect the shell’s execution environment.