2010年2月12日 星期五

Read into read

0 意見
I encountered a case where I'm in the middle of a loop that read through a file through the 'read' command, like,

  while read a b c
  do
    .. (do something) ..
    # need user to input something
    read X
    .. (do some more things) ..
  done < file.txt

The 'read X' inside the loop will read data from the file 'file.txt' instead of console.

To solve the problem, simple change the 'read X' into
  read X < /dev/console
that forces the script reads the input from the terminal.

If you are connecting using SSH, replace /dev/console with your current console device.  You can see your current terminal device file by the environment variable $SSH_TTY (for OpenSSH) that usually is /dev/pts/0, /dev/pts/1 and so on.

Put a shell script function into background

0 意見
To run several shell script processes, but don't want the hassle of maintaining multiple scripts?  Yes, you can put them into functions within ONE script.  It's elegant, beautiful, and much easier to read and maintain.

Here is an example:
1  #!/bin/bash
2  #
3  # Test shell script with background function(s)
4  #
5
6  func1 ()
7  {
8    cat /dev/null > func1.txt
9    i=0
10   while [ $i -le 100 ];
11   do
12   echo $i >> func1.txt
13     echo "From func1: $i"
14   sleep 1
15   (( i = i + 1 ))
16 done
17 }
18
19 func2 ()
20 {
21   cat /dev/null > func2.txt
22   j=0
23   while [ $j -le 10 ];
24   do
25     echo $j >> func2.txt
26     echo "From func2: $j"
27   sleep 6
28   (( j = j + 1 ))
29   done
30 }
31
32 func1 &
33 x=$!
34 echo "func1 PID: $x"
35
36 func2 &
37 y=$!
38 echo "func2 PID: $y"
39
40 echo "Waiting for both function finishing..."
41 wait $y
42 wait $x
43
44 echo "Both function finishing, quit the main script."

As in shell prompt, we can add an '&' after the name of the calling functions (line 32,36), to put them into background.  In other words, the shell duplicates the original processes into several processes, as below:
debian-lenny:~# ps -ef | grep test
user      3517  3337  0 03:06 pts/0    00:00:00 /bin/bash ./test-bg.sh
user      3518  3517  0 03:06 pts/0    00:00:00 /bin/bash ./test-bg.sh
user      3521  3517  0 03:06 pts/0    00:00:00 /bin/bash ./test-bg.sh
Where 3517 is the parent process, and 3518 and 3521 are the duplicates.

In line 33 and 37, use the '$!' to get their Process IDs (PID), that are, 3518 and 3521 respectively.

Finally, use the 'wait' function (in line 41 and 42) for waiting them both finish, before printing the final message and exit.

This is quite useful in doing some tasks, like running multiple instances of file copy - that speeds things up.
 
My Unix Notes | © 2011 Design by DheTemplate.com and Theme 2 Blog

Find more free Blogger templates at DheTemplate.com - Daily Updates Free Blogger Templates