Using Shell Redirection: All About the Here-Doc

Using Shell Redirection: All About the Here-Doc

 

 

 

When gathering information from remote AIX hosts using SSH (Secure Shell), it will definitely make your life a lot easier to write the commands within a here-doc block. A here-doc is a form of shell redirection that takes the command(s) supplied and redirects as input into another command or shell. Here-docs usage is common when you have locally based scripts where you may need to output a lot of text, i.e. help pages, mailing scripts. FTP scripts often contain here-doc method approach, due to parsing authentication details and the interactive commands required by a FTP connection. There are lots more uses for the here-doc. I've just noted a few. So what is a here-doc?

Choose a Word For Redirection

The common use of the here-doc syntax is:

command << delimiter
command(s)
delimiter

Where delimiter is the 'word' of choice, chosen by you (as long as it is not a SHELL reserved word). A common delimiter word is “block” or “EOF”. I usually use the word “mayday”. Now everything from the first to second occurrence of the word will be taken as input to the command or shell. Though you can put single quotes around the first occurrence of the word, this will not let variables get expanded and will not interpret variables as is. If you put a (-) hash before the word, you can indent your here-doc block commands with tabs only, this has the advantage of making the code much easier to read for others. The syntax for this is:

command << - 'delimiter'
command(s)
delimiter

Imagine you have a here-doc that generates lots of output for a report. How can you save it to an output file? You can either redirect the output of the script that contains the here-doc: assume the script is called: myprog, the output goes to the file :outputfile.txt:

$ myprog >outputfile.txt

Or with the here-doc at the start of the block, like so:

command << delimiter > outputfile
command(s)
delimiter

The following in Listing 1 redirects every command into the cat command. The word I’m using is “mayday”. Everything from the first occurrence to the second occurrence will be treated as input into the cat command. In this example the 'whoami' command is output, also with some text output. Along with the current host the script is running on and was last rebooted. The output this example generates is perhaps not meaningful at best, but what it does is demonstrate what a here-doc can do.

Listing 1

#!/bin/sh
cat <<mayday
Hello $(whoami)
Just to let you know the system was last rebooted:
$(who -b)
 Anyway good-bye
mayday

Let's look at another redirection example. This is using the mail command. See Listing 2. Everything from the first word “mayday” to the second occurrence of “mayday” will be treated as input to the mail command. It then emails out to myself, along with the df command output. The prtconf (AIX configuration listing) output is generated to a file and sent as an attachment with the mail. If this was in a production environment, the here-doc would most certainly contain a lot more useful information.

Listing 2

#!/bin/sh
list="david.tansley@btinternet.com"
mail -s "`hostname` Here's your report" $list <prtconf.txt) $(uuencode prtconf.txt prtconf.txt) lots more lines can go here... ... mayday 

When dealing with a here-doc it’s important to note that there should only be one redirection to a command. If you try having two redirects going into the same command, expect some spurious output.

Use a Loop to Feed The Here-doc With SSH Connection

When putting together a script to connect to many remote hosts (one at a time), it’s best to put all the remote host names into a file, then cat the file in a “while” loop or into a “for” loop for your SSH connections. If you only have a few remote hosts to connect to, then put them in a variable list and use a “for” loop to read them in. Here’s three code blocks as examples:

The remote hosts file:

# cat hosts.txt
remote_host1
remote_host2
…

1). Using cat and the while loop to feed SSH.

cat hosts.txt | while read host
do
 done 

2). Using a variable to a list of hosts to feed SSH

dest_hosts=”remote_host1 remote_host2”
for host in $dest_hosts
do
<commands>
done

3). Using a variable and the cat command to feed SSH

dest_hosts=$(cat hosts.txt)
for host in $dest_hosts
do
<commands>
done

SSH And Here-docs Are Great Partners

Using the here-doc with SSH is an efficient way to execute remote commands, like generating reports or installing software, or doing general AIX housekeeping tasks; the list is endless.

Let’s see a more constructive script using SSH incorporating a here-doc. Assume you have been given the task of collating all remote AIX hosts with their respective VG (Volume Group) sizes and free space unallocated to be all presented in GB. See Listing 3.

In the following example the remote hosts file: hosts.txt is cat into the variable $dest_host, a “for” loop then executes for each hostname. Every command contained after the word 'mayday’ to the next occurrence of ‘mayday’, is redirected into SSH. Thus the commands contained in the here-doc will be executed on the remote host. On each remote host we connect to we simply grab a list of the VG's into the variable $list, then execute another “for” loop, to get the total and free sizes of each VG on that remote host. The results are echoed out in comma separated fields which could then be redirected into a file as a CSV import file. The redirection of the output is not shown as this was previously explained earlier how to achieve this.

Listing 3.

#!/bin/sh
echo "Hostname,VG,Total GB,Free GB"
dest_host=$(cat myhosts.txt)
for host in $dest_host
do
ssh -T -l root $host<< 'mayday'
myhost=$(hostname -s)

list=$(lsvg)
for loop in $list
do
total=$(lsvg -L $loop| awk '/TOTAL PP/'| awk '{print $7}'| sed 's/^.//')
free=$(lsvg -L $loop| awk '/FREE PP/'| awk '{print $7}'| sed 's/^.//')
gb_total=$(expr $total / 1024)
gb_free=$(expr $free / 1024)
echo "$myhost,$loop,$gb_total,$gb_free"
done
mayday
done

In my office we have over 250 AIX hosts, just imagine doing that manually ! Typical output of the script in Listing 3. Could look like :

Hostname,VG,Total GB,Free GB
uk01aix9001,rootvg,112,22
uk01aix9001,apollovg,5365,242
uk01aix9001,apollo_sy_vg,3028,127
uk01aix9001,hfc_vg,496,22
uk01aix9002,rootvg,112,27
uk01aix9002,portal_vg,256,0
uk01aix9002,apollo_vdi,112,16

A Quote Will Preserve The Variables

Looking at Listing 3, note that I use single quotes around the word 'mayday'. This is required because I need to assign variables with their current values; I do not require the variables to be expanded. Thus the use of quotes. If I didn’t then I would get a load of 'not found', 'syntax error' statements thrown up when the here-doc is executed on the remote host.

Conclusion

Using here-docs especially in a SSH environment is a great way to execute many commands on a remote host, in fact it is a script with in a script if one thinks about it. I use this method all the time in my office for adding/removing users, remote editing files with sed or text processing with awk, as well as package installs or just general MIS gathering reports.

0 (0)
Article Rating (No Votes)
Rate this article
Attachments
There are no attachments for this article.
Comments
There are no comments for this article. Be the first to post a comment.
Full Name
Email Address
Security Code Security Code
Related Articles RSS Feed
AIX Password expiry /etc/passwd
Viewed 18547 times since Wed, Jul 3, 2019
10 Awk Tips, Tricks and Pitfalls
Viewed 5834 times since Wed, Aug 19, 2020
AIX - How to shutdown or reboot
Viewed 5273 times since Fri, Jun 8, 2018
AIX↑ AIX www links
Viewed 3659 times since Sat, Apr 20, 2019
List of 10 Must Know Oracle Database Parameters for Database Administrator
Viewed 123494 times since Thu, Jun 21, 2018
AIX - How to get Memory infomation
Viewed 9779 times since Fri, Jun 8, 2018
Oslevel shows wrong AIX’s level. Why
Viewed 4667 times since Thu, Feb 21, 2019
AIX Replacing a failed disk (rootvg)
Viewed 8456 times since Tue, Jul 17, 2018
AIX, Monitoring, Networking, Red Hat, Security, System Admin↑ Determining type of system remotely
Viewed 2177 times since Fri, Apr 19, 2019
AIX, Installation, NIM↑ Creating an LPP source and SPOT in NIM
Viewed 14646 times since Fri, Apr 19, 2019