Loops in shell scripts
|
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.
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."
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
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.
« Previous 1 2 3 4 Next »
Buy this article as PDF
Pages: 5
(incl. VAT)