Monday, January 10, 2011

Suspending and resuming a running process in Linux

In Linux, a running process or command execution can be stopped in one terminal and made it to run from other terminal.  Let say you triggered a cp command for copying some huge volumes of data from one filesystem to other, from your own workstation. After initiating the command you realized that it would take more time to complete. In this situation, you got to deal with 2 issues. One is, incase you lost the connection to server, the command execution will stop, and other one is that you have to keep your workstation connected until the command execution completes.

Solution:

1.   Making the job to run in back-ground is a simple solution but it is not always possible to do it, when your script/command needs some set of inputs. Syntax for making a command execution to run in the back-ground is as follows:  # nohup  <command set> &     
(e.g   # nohup cp -apR /somefolder  /otherfolder & ).

2.   Start the job on first terminal (say Terminal-A). Open another terminal (say Terminal-B) where you can run the job uninterruptedly. On Terminal-B find out the Parent Process ID (PPID) of the Job which you started on Terminal-A. 
Execute the kill command with signal 19 to Suspend the process  
             # kill -19 <PID>
Go to Terminal-A and press Ctrl+z
Then come back to Terminal-B and execute the kill command with signal 18 to Continue the process
            # kill -18 <PID>
Exit from Terminal-A by running ‘exit’ command, Now your job/process will continue to run on Terminal-B.

Note: Please ensure that you suspend the PPID (Parent PID) of the Job (not the PID of its child process).  If you suspend the PID of child process and exit from Terminal-A, the parent process will get hang-up signal and terminate the execution, and the PID which you suspended will become defunct process.

Sunday, January 2, 2011

Monitoring command execution at regular intervals

I use these 2 methods to monitor command execution at regular intervals. One by using the command “watch” and another by using a small while statement.


Using watch command:
 # watch -n <time interval in seconds>  “command” or just  # watch  “command”


Examples:
# watch -n 10 "cat /proc/meminfo | grep -i Mem"      <- Watch Memory utilization at 10 seconds intervals
# watch -n 15 10 “du -sh |  grep /somefilesystem”     <- Watch disk utilization at 15 seconds interval.
# watch "ps aux|grep jboss"                                     <- Watch jboss process with default time interval


Using while statement:
while true; do <commands separated by semicolon>; sleep <time interval in seconds>; done  


Examples:

[adevaraju@hostxyz ~]$ while true; do cat /proc/meminfo | grep -i mem; uptime; echo; sleep 10; done
MemTotal:      4194480 kB
MemFree:         36776 kB
 01:52:51 up 14 days,  9:07,  1 user,  load average: 0.00, 0.00, 0.00


MemTotal:      4194480 kB
MemFree:         36652 kB
 01:53:01 up 14 days,  9:07,  1 user,  load average: 0.00, 0.00, 0.00


MemTotal:      4194480 kB
MemFree:         36776 kB
 01:53:11 up 14 days,  9:07,  1 user,  load average: 0.00, 0.00, 0.00


# while true; do echo Current time is  `date "+%H Hour: %M Minutes: %S Seconds"`; sleep 4; done
Current time is 01 Hour: 47 Minutes: 26 Seconds
Current time is 01 Hour: 47 Minutes: 30 Seconds
Current time is 01 Hour: 47 Minutes: 34 Seconds
Current time is 01 Hour: 47 Minutes: 38 Seconds
Current time is 01 Hour: 47 Minutes: 42 Seconds
Current time is 01 Hour: 47 Minutes: 46 Seconds
Current time is 01 Hour: 47 Minutes: 50 Seconds
Current time is 01 Hour: 47 Minutes: 54 Seconds
Current time is 01 Hour: 47 Minutes: 58 Seconds
Current time is 01 Hour: 48 Minutes: 02 Seconds
Current time is 01 Hour: 48 Minutes: 06 Seconds
#
PS:  “watch” command wouldn’t work properly if the command sets are complex. It will just display the result of first iteration and stay there forever.