You have a file data.txt which has a field YEAR_MONTH:
YEAR_MONTH="201211"
And you wish to change the value to reflect the current year and month. You could use sed to automate this process with a one-line sed program:
sed -e "s/YEAR_MONTH=\"20[0-9][0-9]\(\(0[1-9]\)\|\(1[0-2]\)\)\"/YEAR_MONTH=\"`date +%Y%m`\"/g"
Note:
1. You need to use double-quotes "..." to encapsulate the entire sed program string so that the `date` command will be executed by the shell before it passes the sed program string to sed.
2. You will need to escape the inner double-quotes and the parentheses ( ) with backslashes to avoid them being interpreted by the shell.
3. 20[0-9][0-9]((0[1-9])|(1[0-2])) means all values from 200001 to 209912
Thursday, November 1, 2012
Friday, May 4, 2012
Unix: How to ensure only one instance of a Unix script is running
There are times when you need to ensure only one instance of your program or script is running. The reason for this is usually related to maintaining data integrity.The common general mechanism employed by any program/script to ensure itself to be the single running instance is simply this:
1. Check if a specified condition exist
2. If the condition does not exist, create the condition and continue running; else exit
The mechanism appears straightforward but there is one problem - there are 2 distinct steps in the mechanism. In modern day multiprocessing operating systems, these 2 steps within a program cannot be guaranteed to be run in succession. To show why this is a concern, we look at 2 scenarios of two instances of a program started somewhat concurrently. We will assume the condition to be checked does not exist in both scenarios.
Scenario 1
Scenario 2
In scenario 2, we have condition checking and the ensuing action executed as 2 continuous sub-steps within one complete (bigger) step. We term this as an atomic operation - an operation which is indivisible. The 2 sub-steps within the atomic step must be completed one after another or none at all. This way, there is a guarantee only either of the two instances will end up running.
Compiled languages in general usually have facilities built-in the language or as external API calls for the programmer to guarantee a single running instance of her program. The shell script developer will have to resort to indirect methods to ensure a script will indeed be the sole running instance because of no innate facilities within the typical shell scripting language.
We have at least 3 (indirect) methods for the shell script developer to create a singleton process (i.e single instance process).
Method A - Lock by creating a directory - mkdir is atomic
Method B - Lock by setting Bash/Korn shell's noclobber option
Method C - Lock by creating a fifo - mkfifo is atomic
If allowed by your environment or requirements, /tmp will be a suitable location to create the lock directory, file or FIFO.
Reference:
1. Check if a specified condition exist
2. If the condition does not exist, create the condition and continue running; else exit
The mechanism appears straightforward but there is one problem - there are 2 distinct steps in the mechanism. In modern day multiprocessing operating systems, these 2 steps within a program cannot be guaranteed to be run in succession. To show why this is a concern, we look at 2 scenarios of two instances of a program started somewhat concurrently. We will assume the condition to be checked does not exist in both scenarios.
Scenario 1
In scenario 1, Instance-A checks
for the condition and detects the condition does not exist yet, all within execution cycle-1. Before
it could create the condition, the OS's process scheduler swaps it out
(makes a context switch) and executes Instance-B in cycle-2. Instance-B also now thinks the
condition is missing. At this point, each instance thinks it is the only one about to run - but both continue to run after creating the conditions (assuming repetitive creation of the condition is not flagged as a problem).
Scenario 2
In scenario 2, we have condition checking and the ensuing action executed as 2 continuous sub-steps within one complete (bigger) step. We term this as an atomic operation - an operation which is indivisible. The 2 sub-steps within the atomic step must be completed one after another or none at all. This way, there is a guarantee only either of the two instances will end up running.
Compiled languages in general usually have facilities built-in the language or as external API calls for the programmer to guarantee a single running instance of her program. The shell script developer will have to resort to indirect methods to ensure a script will indeed be the sole running instance because of no innate facilities within the typical shell scripting language.
We have at least 3 (indirect) methods for the shell script developer to create a singleton process (i.e single instance process).
Method A - Lock by creating a directory - mkdir is atomic
/tmp/myprog$ ls
/tmp/myprog$ mkdir lock_dir
/tmp/myprog$ ls
lock_dir
/tmp/myprog$ mkdir lock_dir
mkdir: cannot create directory `lock_dir': File exists
/tmp/myprog$
/tmp/myprog$ mkdir lock_dir
/tmp/myprog$ ls
lock_dir
/tmp/myprog$ mkdir lock_dir
mkdir: cannot create directory `lock_dir': File exists
/tmp/myprog$
- After creating the lock directory, you could create a file under this directory containing the PID of the locking process.
Method B - Lock by setting Bash/Korn shell's noclobber option
/tmp/myprog$ ls
/tmp/myprog$ set -o noclobber
/tmp/myprog$ echo "1" > lock_file
/tmp/myprog$ ls
lock_file
/tmp/myprog$ echo "2" > lock_file
bash: lock_file: cannot overwrite existing file
/tmp/myprog$
/tmp/myprog$ set -o noclobber
/tmp/myprog$ echo "1" > lock_file
/tmp/myprog$ ls
lock_file
/tmp/myprog$ echo "2" > lock_file
bash: lock_file: cannot overwrite existing file
/tmp/myprog$
- It's good to have the PID of the locking process stored in the lock file.
Method C - Lock by creating a fifo - mkfifo is atomic
/tmp/myprog$ ls -l
total 0
/tmp/myprog$ mkfifo ./lock_fifo
/tmp/myprog$ ls -l
total 0
prw-r--r-- 1 openet openet 0 2012-05-04 16:41 lock_fifo
/tmp/myprog$ mkfifo ./lock_fifo
mkfifo: cannot create fifo `./lock_fifo': File exists
/tmp/myprog$
If allowed by your environment or requirements, /tmp will be a suitable location to create the lock directory, file or FIFO.
Reference:
- UNIX Network Programming, Volume 2: Interprocess Communications (2nd Edition) - Richard Stevens
Subscribe to:
Posts (Atom)

