A here document is nothing but I/O redirection that tells the bash shell to read input from the current source until a line containing only delimiter is seen.
This is useful for providing commands to ftp, cat, echo, ssh and many other useful Linux/Unix commands. This feature should work with bash or Bourne/Korn/POSIX shell too.
heredoc syntax
The syntax is:
command <<EOF cmd1 cmd2 arg1 EOF
OR allow here-documents within shell scripts to be indented in a natural fashion using EOF
command <<-EOF msg1 msg2 $var on line EOF
OR
command <<'EOF' cmd1 cmd2 arg1 $var won't expand as parameter substitution turned off by single quoting EOF
OR redirect and overwrite it to a file named my_output_file.txt:
command <<EOF > my_output_file.txt mesg1 msg2 msg3 $var on $foo EOF
OR redirect and append it to a file named my_output_file.txt:
command <<EOF >> my_output_file.txt mesg1 msg2 msg3 $var on $foo EOF
Examples
The following script will write the needed contents to a file named /tmp/output.txt:
#!/bin/bash OUT=/tmp/output.txt echo "Starting my script..." echo "Doing something..." cat <<EOF >$OUT Status of backup as on $(date) Backing up files $HOME and /etc/ EOF echo "Starting backup using rsync..."
You can view /tmp/output.txt with the cat command:
$ cat /tmp/output.txt
Sample outputs:
Status of backup as on Thu Nov 16 17:00:21 IST 2017 Backing up files /home/vivek and /etc/
Disabling pathname/parameter/variable expansion, command substitution, arithmetic expansion
Variable such as $HOME and command such as $(date) were interpreted substitution in script. To disable it use single quotes with ‘EOF’ as follows:
#!/bin/bash OUT=/tmp/output.txt echo "Starting my script..." echo "Doing something..." # No parameter and variable expansion, command substitution, arithmetic expansion, or pathname expansion is performed on word. # If any part of word is quoted, the delimiter is the result of quote removal on word, and the lines in the here-document # are not expanded. So EOF is quoted as follows cat <<'EOF' >$OUT Status of backup as on $(date) Backing up files $HOME and /etc/ EOF echo "Starting backup using rsync..."
You can view /tmp/output.txt with the cat command:
$ cat /tmp/output.txt
Sample outputs:
Status of backup as on $(date) Backing up files $HOME and /etc/
A note about using tee command
The syntax is:
tee /tmp/filename <<EOF >/dev/null line 1 line 2 line 3 $(cmd) $var on $foo EOF
Or disable variable substitution/command substitution by quoting EOF in a single quote:
tee /tmp/filename <<'EOF' >/dev/null line 1 line 2 line 3 $(cmd) $var on $foo EOF
Here is my updated script:
#!/bin/bash OUT=/tmp/output.txt echo "Starting my script..." echo "Doing something..." tee $OUT <<EOF >/dev/null Status of backup as on $(date) Backing up files $HOME and /etc/ EOF echo "Starting backup using rsync..."
A note about using in-memory here-docs
Here is my updated script:
#!/bin/bash OUT=/tmp/output.txt ## in memory here docs ## thanks https://twitter.com/freebsdfrau exec 9<<EOF Status of backup as on $(date) Backing up files $HOME and /etc/ EOF ## continue echo "Starting my script..." echo "Doing something..." ## do it cat <&9 >$OUT echo "Starting backup using rsync..."
🐧 2 comments so far... add one ↓
Category | List of Unix and Linux commands |
---|---|
File Management | cat |
Firewall | Alpine Awall • CentOS 8 • OpenSUSE • RHEL 8 • Ubuntu 16.04 • Ubuntu 18.04 • Ubuntu 20.04 |
Network Utilities | dig • host • ip • nmap |
OpenVPN | CentOS 7 • CentOS 8 • Debian 10 • Debian 8/9 • Ubuntu 18.04 • Ubuntu 20.04 |
Package Manager | apk • apt |
Processes Management | bg • chroot • cron • disown • fg • jobs • killall • kill • pidof • pstree • pwdx • time |
Searching | grep • whereis • which |
User Information | groups • id • lastcomm • last • lid/libuser-lid • logname • members • users • whoami • who • w |
WireGuard VPN | Alpine • CentOS 8 • Debian 10 • Firewall • Ubuntu 20.04 |
You can also use heredocs to run stuff:
sudo -s << EOF
yum -y update
yum -y install foo bar
EOF
And all this time I was trying to find a decent tutorial about here documents.
Thanks for this!