Loops in shell scripts

Slashdot it! Delicious Share on Facebook Tweet! Digg!

Pausing with Wait

You can use wait to pause execution of one or more background tasks before continuing. This command doesn't strictly belong to loop control, but it can be used in combination with it. Without this command, a loop would continue running after starting a background task, with some possible undesired results. Using wait ensures that the process stops and all necessary tasks are performed.

Immediately after starting a program, the shell provides its process ID, which you can query with the $! variable. If you want to wait on multiple processes, place each of the IDs in its own variable. You pass the PIDs to wait , and it pauses the loop until all PIDs are removed from the process table.

In practice, the background processes could be database daemons, web servers, or other entities. The two small shell scripts in Listing 9 use only one variable and are put to sleep (so that you can observe the process). Listing 10 shows the content of the shell script a.sh called by the script.

Listing 9

waitamoment.sh

m01 #! /bin/sh
02
03 d=0
04 a=0
05 b=0
06 c=0
07
08 while true
09 do
10 echo -n "Start the script: ";date +%H:%M:%S
11 sh a.sh &
12 PID1=$!
13 sh b.sh &
14 PID2=$!
15
16 echo "Waiting for processes $PID1 and $PID2."
17 wait $PID1 $PID2
18 echo -n "End the script: ";date +%H:%M:%S
19
20 # Applying and calculating the variables
21
22 a=$(cat a.txt)
23 b=$(cat b.txt)
24 c=$(echo $a + $b | bc)
25 d=$(echo $d + $c | bc)
26 echo "Subtotal: $d"
27
28 # Break when d > 30
29
30 if [ $d -gt 30 ];
31    then
32       break
33 fi
34 done
35 echo "Total: $d"

Listing 10

a.sh

01 #! /bin/sh
02 # a.sh
03 n=8
04 sleep 5
05 echo $n > a.txt

Listing 11

b.sh

01 #! /bin/sh
02 # b.sh
03 n=3
04 sleep 2
05 echo $n > b.txt

Listing 11 shows the content of b.sh . Inside the loop, a sum is calculated. When its value exceeds 30, the break ends the loop. Figure 4 shows the entire results.

Figure 4: Result of waitamoment.sh.

A Text Menu

Listing 12 shows a pure text menu for terminal sessions. It runs a while true endless loop that ends with a break , allowing further commands after the loop to be executed. You can use this script as a kind of building block and modify or enhance it as needed. Figure 5 shows the menu in action.

Listing 12

menu.sh

01 #! /bin/sh
02
03 while true
04 do
05 clear
06 echo "     1   nanoeditor"
07 echo "     2   htop"
08 echo "     3   root login"
09 echo "     4   disk usage /home"
10 echo "     9   END"
11 echo "     ---------------"
12 echo -n "     ";read pnr
13 if [ $pnr -eq 1 ]; then nano
14 elif [ $pnr -eq 2 ]; then htop
15 elif [ $pnr -eq 3 ]; then su -
16 elif [ $pnr -eq 4 ]; then df -h /home; sleep 3
17 elif [ $pnr -eq 9 ]; then break; fi
18 done
19 echo "Requested program end."
Figure 5: Menu for a terminal session.

You can create shell programs with GUI operations using Yad . The capabilities far exceed just menu control (you can, for example, use easy masks for database applications). The example shows a lot about the process even at a beginner's level. Listing 13 shows the example, and Figure 6 shows the GUI script in operation.

Listing 13

Example Using Yad

01 #! /bin/bash
02
03 while true;
04 do
05
06 # Determine menu entries, field separator="!", expandable!
07 actions="gedit!gnome-terminal!pcmanfm"
08
09 action=$(yad --title="HEADING_TEXT" --text="TEXT_ABOVE_MENU" \
10 --form \
11 --field="Action: ":CB $actions \
12 --button="Cancel":1 \
13 --button="Start action":0)
14
15 # End program with [CANCEL], use exit code 252 when ending with "X"
16
17 ec=$(echo $?)
18
19 if [ $ec -eq 1 ];
20    then
21        exit
22 elif [ $ec -eq 252 ];
23    then
24        exit
25 fi
26
27 # Read selected action
28
29 action=$(echo $action  | cut -d \| -f1)
30
31 # Call selected program
32
33 exec $action &
34 done
Figure 6: Shell menu using yad.

The menu is in an endless loop. Before the menu, you set a variable with the menu selections in the form MENUITEM1!2MENUITEM2 ….. . The yad GUI sets the action variable with the result of the selection. Its content after selecting the first item is PROGRAM| . The program name is disconnected from the separator symbol with the cut command.

The exec command starts the program in the background so that it's possible always to access the menu and start other programs. If this is not what you want, you can just remove the & character at the end of the exec line.

The yad --form presents the selection in the --field , leading to the CB (Check box) option. Ending the loop involves evaluating the exit code, which you derive using the button statement (here with preset values). If you want to end the script by using X , you need to add a 252 after the 1 .

For the example, the actions were defined as the gedit editor, the gnome-terminal , and pcmanfm . You can substitute your favorite programs and change the headings as you wish.

Buy this article as PDF

Express-Checkout as PDF

Pages: 5

Price $0.99
(incl. VAT)

Buy Ubuntu User

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content