TimeLinux1

Wednesday, March 6, 2013

Heredoc to automate shell scripts

Ever wondered if there was a way to automate passing multiple bash commands to run non interactively?
For instance, if you wanted to create a shell script to start vi editor, get into insert mode and populate some commands based on some condition and then escape, save and exit out of the editor all while being in the shell script--how would you do it?

The answer is what is called heredoc. The concept of heredoc comes from C programming language and which was later borrowed into Unix/Linux tradition. Basically what a heredoc does is to accept commands from a stream starting with a start-signature and ending with the same signature. So all the commands or interactions with the shell between those start-end signatures are non-interactive.
For a more detailed discussion visit heredoc pages here and here.

An Example:

#-------------


[root@redhat2 mrinal]# cat myscript
#!/bin/bash

tfile=$1

vi $tfile << bye                      /* start vi with a file argument $tfile by user & start signature = bye*/
i                                              /* invoke 'insert' mode of vi */
echo `date`                              /* run a command */
`uname -a`                              /* run another command */
`ls -l`
^[                                            /* escape to command mode of vi, passed by Ctrl+v on keyboard */
wq                                          /* save file */
bye                                      /* end non interactive mode when sees the signature = bye */

#------------

The above shell script will open vi non-interactively and run a bunch of commands between the start-end signature, here in our case the word 'bye'. It could be anything you choose, as long the start and end signatures are the same. 

How to add swap in Linux

Swap space is a special filesystem in Linux that acts as virtual memory.
Virtual memory is not real or physical memory like the DIMM/SIMM modules you would install on your computers motherboard. Rather its a dedicated  piece of your computer's hard disk that looks and feels like a physical memory. Virtual memory is used by the system whenever there is a shortage of Real memory to accomodate all running programs in a multiuser, multiprogramming system like Linux. Think of a user running several programs simultaneously (a browser, a word processor, an email client, a vim editor, a video player etc). This situation would demand that all the running programs (ie processes) exist in (physical) memory. If the physical memory is not sufficient to hold all the programs then the less used programs would be 'swapped' to the swap space to make room for the more demanding processes. This ensures the system keeps running all the programs and servicing the user instead of crashing suddenly.

Now that we know a bit about swap space and why its needed, lets look at how we can add more swap space to a system.
Essentially, there are two ways to add swap space:
      1- add a new physical hard disk or partition and assign that as additional swap
      2- add a new file on your file-system and assign that as additional swap.

First to check the swap before adding new swap, we run swapon command as follows:



[root@redhat4 ~]# swapon -s
Filename Type Size Used Priority
/dev/dm-1                               partition 6160376 228 -1

This shows the system has about 6 GB of swap to begin with. Now we try each one of the two methods listed above

1- To add a new physical hard disk or partition and assign that as additional swap:

Lets say we have a new device /dev/sdc as a free hard disk / partition, then to make it as swap:

[root@redhat4 ~]# mkswap /dev/sdc1

Then enable the swap partition for usage using swapon command as shown below.

[root@redhat4 ~]#swapon /dev/sdc1

Then verify that the new swap partition is now available for use (assuming /dev/sdc1 was 1GB in size)

[root@redhat4 ~]# swapon -s
Filename Type Size     Used  Priority
/dev/dm-1                         partition   6160376 228  -1
/dev/sdc1                          partition    1048568         0     -2

To make the new swap partition available after reboot add the following line to /etc/fstab

[root@redhat4 ~]# cat /etc/fstab
/dev/sdc1               swap                    swap    defaults        0 0

Thats it for adding a new disk or partition as swap. Now to the 2nd method of adding a file as swap.

2- To add a new file on your file-system and assign that as additional swap:

First lets examine the initial swap:


[root@redhat4 ~]# swapon -s
Filename Type Size Used Priority
/dev/dm-1                               partition 6160376 228 -1

Lets add a 10 GB file created using dd utility (disk dump utility) as follows:
(obviously, you would want to make sure you have 10GB free on your filesystem before doing so)


[root@redhat4 ~]# dd if=/dev/zero of=/root/myswapfile bs=1M count=10000
10000+0 records in
10000+0 records out
10485760000 bytes (10 GB) copied, 824.221 s, 12.7 MB/s

Then check the new file and change its permissions to 600 so only root can use it.


[root@redhat4 ~]# ls -l /root/myswapfile
-rw-r--r--. 1 root root 10485760000 Mar  6 09:48 /root/myswapfile
[root@redhat4 ~]# chmod 600 /root/myswapfile

[root@redhat4 ~]# ls -l /root/myswapfile
-rw-------. 1 root root 10485760000 Mar  6 09:50 /root/myswapfile

Then make this new file as swap:


[root@redhat4 ~]# mkswap /root/myswapfile
mkswap: /root/myswapfile: warning: don't erase bootbits sectors
        on whole disk. Use -f to force.
Setting up swapspace version 1, size = 10239996 KiB
no label, UUID=c83a0679-aa64-4a42-85ee-851f4d7bab60

Then enable this new file as swap:

[root@redhat4 ~]# swapon /root/myswapfile

Then verify that all looks good.

[root@redhat4 ~]# swapon -s
Filename Type Size Used Priority
/dev/dm-1                               partition 6160376 228 -1
/root/myswapfile                        file 10239992 0 -2

[root@redhat4 ~]# free -m
             total       used       free     shared    buffers     cached
Mem:          9893       9702        190          0         33        648
-/+ buffers/cache:       9019        873
Swap:        16015          0      16015

To make this new file available as swap across reboots, add the following line in /etc/fstab:

UUID=c83a0679-aa64-4a42-85ee-851f4d7bab60  swap swap    defaults        0 0


And thats it. You now have a new swap space in your system!