1. For command
The For command is very useful when dealing with repetitive tasks. The usage syntax is as follows.
.
for var in list
do
commands
done
Repetitive variable input must be provided through a list. Enter the commands to be executed between do and done.
read variable value from list
One of the ways to use a list is to list values by separating them with a space as shown below.
#! /bin/bash
#Example of using list in for statement
for test in seoul busan daegu daejun incheon kwangju
do
echo the next city is $test
done
#
If you run it, you can see that the city names are output line by line as shown below.
$ ./test1
the next city is seoul
the next city is busan
the next city is daegu
the next city is daejun
the next city is incheon
the next city is kwangju
If the input variable has single quotation marks, it is treated as a single variable value by either putting a backslash in front of it or enclosing it in double quotation marks. If you create an example,
it will work like this:
#!/bin/bash
# another example of how not to use the for command
for test in I don’t know if this’ll work
do
echo "word:$test"
done
#
When executed, single quotes (dont know it thisll) are treated as a single variable. To avoid this, either enclose it in double quotation marks or use a backslash before single quotation marks.
$ ./badtest1
word:I
word:dont know if thisll
word:work
$
Reading a list value from a variable.
If you put multiple values in a variable and save it in a list, you can see the same effect as listing the variable values. Let's look at an example.
#! /bin/bash
# Example of using list in for statement
list="seoul busan daegu daejun incheon kwangju"
city=$list
for test in $city
do
echo the next city is $test
done
let's run
$ ./test2
the next city is seoul
the next city is busan
the next city is daegu
the next city is daejun
the next city is incheon
the next city is kwangju
read value from command
can also read the value from the output result of the command. If you specify the command to be executed using backticks (`), the output result can be used within the for statement. Let's look at an example. First, I put the city name in a file called city as follows.
$ cat city
seoul
busan
daegu
kwangju
tongyoung
Write the script as below.
#! /bin/bash
#read input from file
file="city" ==> Enter the file name of city in the file variable
for city in `cat $file` => The cat command, surrounded by backticks, reads the file stored in file.
do
echo "Visit place is $city"
done
If you run it, you can see that it works well as below.
$ ./test3
Visit place is seoul
Visit place is busan
Visit place is daegu
Visit place is kwangju
Visit place is tongyoung
Changing the field delimiter
In Linux, the definition of the field separator used by the Shell separates characters according to the value defined in IFS (Intenal Field Seperator). Basically, the following three are defined.
■ A space
■ A tab
■ A newlin
When the shell encounters one of the three above, it is considered that new data is started. Let's create an example of how to change it when writing a script. This is when the IFS value is set to a new line.
#!/bin/bash
# reading values from a file
file="states"
IFS=$’\n’
for state in `cat $file`
do
echo "Visit beautiful $state"
done
When used as above, spaces or tabs are ignored and only newlines are used as data delimiters. A point to be aware of is that it is often caused by forgetting to change the IFS and not restoring to the default value. For this, it is recommended to write the following recovery code in the script.
#
IFS.OLD=$IFS
IFS=$’\n’
‹use the new IFS value in code›
IFS=$IFS.OLD
#
The semicolon is the most used delimiter. To use it, ifs=; If set to , data is separated by semicolons. If you want to use multiple IFS delimiters, you can list the field delimiters.
For example, IFS=$'\n':;" ==> Use newlines, colons, semicolons, and double quotation marks as delimiters.
Reading a directory using wildcards
Sometimes when you want to do something by reading all the files in a directory, you can use wildcards to do this. Let's look at an example. And if you want to check multiple directories, you can enumerate the directories separated by a space after in.
#! /bin/bash
#Reading a directory using wildcards
for wild in /home/hyowon/*
do
if [ -d "$wild" ]
then
echo "$wild is a directory"
else [ -f "$file" ]
echo "$wild is a file"
fi
done
#
let's run script
$ ./test4
/home/hyowon/NPKI is a directory
/home/hyowon/Steam is a directory
/home/hyowon/VirtualBox VMs is a directory
/home/hyowon/deja-dup is a directory
/home/hyowon/dir.Iu6oW4 is a directory
/home/hyowon/dir.d03tYD is a directory
/home/hyowon/kdenlive is a directory
/home/hyowon/path is a directory
/home/hyowon/snap is a directory
/home/hyowon/test is a directory
/home/hyowon/test12 is a directory
/home/hyowon/workspace is a directory
/home/hyowon/공개 is a directory
/home/hyowon/다운로드 is a directory
/home/hyowon/문서 is a directory
/home/hyowon/바탕화면 is a directory
/home/hyowon/비디오 is a directory
/home/hyowon/사진 is a directory
/home/hyowon/음악 is a directory
/home/hyowon/템플릿 is a directory
2. Using the C language style
The shell supports programming forms in the C language. An example of one of them is as follows:
#!/bin/bash
# testing the C-style for loop
for (( i=1; i ‹= 10; i++ ))
do
echo "The next number is $i"
done
#
Multiple variables can be used in a declaration statement. How to use is as follows.
#!/bin/bash
# testing the C-style for loop
for (( i=1; i ‹= 10; i++ ))
do
echo "The next number is $i"
done
#
3. Using the While command
You can think of the while command as a command that can see the effects of if-then and for statements together. The usage syntax is as follows. And if you want to use multiple test statements, list the test statements separated by spaces in the while statement.
example
#
while test command ==> Execute other commands repeatedly while test command is true
do
other commands
done
#
Let's look at an example script.
$ cat test10
#!/bin/bash
# while command test
var1=10
while [ $var1 -gt 0 ] ==> Repeat until the value of var1 is greater than 0
do
echo $var1 ==>print var1
var1=$[ $var1 - 1 ] ==> Decrements the value of var1 by onevar1
done
let's run script
$ ./test10
10
9
8
7
6
5
4
3
2
1
$
4. until command
The until command is the opposite of the while command. If the exit code is non-zero, the iteration continues. Let's look at an example as below.
#!/bin/bash
# using the until command
var1=100
until [ $var1 -eq 0 ] ==> Repeat the command below do until var1 equals 0.
do
echo $var1
var1=$[ $var1 - 25 ]
done
#
let's run script
$ ./test
100
75
50
25
$
5. nested loop statement
nested loop statements allow execution of another loop statement within a loop. Let's look at an example below.
#!/bin/bash
# placing a for loop inside a while loop
var1=5
while [ $var1 -ge 0 ] ==>Repeat until the value of var1 is equal to or greater than 0
do
echo "Outer loop: $var1"
for (( var2 = 1; $var2 ‹ 3; var2++ ))
==> inner loop, iterates continuously when the value of var2 is less than 3.
do
var3=$[ $var1 * $var2 ]
echo " Inner loop: $var1 * $var2 = $var3"
done
var1=$[ $var1 - 1 ]
done
#
let's run script
$ ./test5
Outer loop 5
Inner loop: 5 * 1=5
Inner loop: 5 * 2=10
Outer loop 4
Inner loop: 4 * 1=4
Inner loop: 4 * 2=8
Outer loop 3
Inner loop: 3 * 1=3
Inner loop: 3 * 2=6
Outer loop 2
Inner loop: 2 * 1=2
Inner loop: 2 * 2=4
Outer loop 1
Inner loop: 1 * 1=1
Inner loop: 1 * 2=2
Outer loop 0
Inner loop: 0 * 1=0
Inner loop: 0 * 2=0
6. Repeat file data search
Sometimes it is necessary to repeatedly process data in a file. In this case, there are two main ways to deal with it:
■ Use of duplicate loops
■ Change the IFS value
Let's create and run an example that searches the /etc/passwd file
#! /bin/bash
#excute nested loop after changing IFS value
IFS.OLD=$IFS
IFS=$'\n'
for entry in `cat /etc/passwd`
do
echo "Values in $entry"
IFS=:
for values in $entry
do
echo " $values"
done
done
let's run script
$ ./test6
Values in root:x:0:0:root:/root:/bin/bash
root
x
0
0
root
/root
/bin/bash
Values in daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
daemon
x
1
1
daemon
/usr/sbin
/usr/sbin/nologin
Values in bin:x:2:2:bin:/bin:/usr/sbin/nologin
7. Control the Loop
There is a way to control the loop when the loop is executed. You can do that by writing a script using the command below.
■ break command : Breaks out of the loop.
■ continue command: Executes the next loop without exiting the loop.
Example of using break command
1) Example of escaping from loop in for statement
#!/bin/bash
# breaking out of a for loop
for var1 in 1 2 3 4 5 6 7 8 9 10
do
if [ $var1 -eq 5 ] ===> When var1 is 5
then
break ==> Exit the loop.
fi
echo "Iteration number: $var1"
done
echo "The for loop is completed"
let's run script
$ ./test17
Iteration number: 1
Iteration number: 2
Iteration number: 3
Iteration number: 4
The for loop is completed
$
2) Example of use in until statement
#!/bin/bash
# breaking out of a while loop
var1=1
while [ $var1 -lt 10 ]
do
if [ $var1 -eq 5 ]
then
break
fi
echo "Iteration: $var1"
var1=$[ $var1 + 1 ]
done
echo "The while loop is completed"
#
let's run script
$ ./test18
Iteration: 1
Iteration: 2
Iteration: 3
Iteration: 4
The while loop is completed
$
3) Exiting the inner loop from the duplicate loop
#!/bin/bash
# breaking out of an inner loop
for (( a = 1; a ‹ 4; a++ ))
do
echo "Outer loop: $a"
for (( b = 1; b ‹ 100; b++ ))
do
if [ $b -eq 5 ]
then
break
fi
echo " Inner loop: $b"
done
done
#
let's run script
$ ./test1
Outer loop: 1
Inner loop: 1
Inner loop: 2
Inner loop: 3
Inner loop: 4
Outer loop: 2
Inner loop: 1
Inner loop: 2
Inner loop: 3
Inner loop:4
Outer loop: 3
Inner loop:1
Inner loop:2
Inner loop:3
Inner loop:4
$
4) Exit from inner loop to outer loop
In a nexted loop, the break n command provides a way to break out of the nested loop at once. In the above example, even if you exit the inner loop, the outer loop is repeated. However, if break 2 is entered in the above script, the outer loop will also be terminated. Here, n is a parameter value that determines how many steps to exit.
Using the continue command
This command does not terminate the loop, but skips the test under the condition that continu takes place and moves on to the next loop. Let's look at an example below.
#!/bin/bash
# using the continue command
for (( var1 = 1; var1 ‹ 15; var1++ ))
do
if [ $var1 -gt 5 ] && [ $var1 -lt 10 ]
==>If var1 is >5, <10, the next loop is not executed without executing the echo
statement.
then
continue
fi
echo "Iteration number: $var1"
done
If you run it, the echo statements from 6 to 9 are not executed.
$ ./test21
Iteration number: 1
Iteration number: 2
Iteration number: 3
Iteration number: 4
Iteration number: 5
Iteration number: 10
Iteration number: 11
Iteration number: 12
Iteration number: 13
Iteration number: 14
$
Continue can set how many steps to skip like break. How to use Continue n is specified as a value.
Let's take a look at an example.
#!/bin/bash
# continuing an outer loop
for (( a = 1; a ‹= 5; a++ ))
do
echo "Iteration $a:"
for (( b = 1; b ‹ 3; b++ ))
do
if [ $a -gt 2 ] && [ $a -lt 4 ]
==>When the value of A is greater than 2 and less than 4 (3), skip step 2 (1,2) in
the inner loop
then
continue 2
fi
var3=$[ $a * $b ]
echo "The result of $a * $b is $var3"
done
done
let's run it
$ ./test
Iteration 1:
The result of 1 * 1 is 1
The result of 1 * 2 is 2
Iteration 2:
The result of 2 * 1 is 2
The result of 2 * 2 is 4
Iteration 3:
Iteration 4:
The result of 4 * 1 is 4
The result of 4 * 2 is 8
Iteration 5:
The result of 5 * 1 is 5
The result of 5 * 2 is 10
$
Processing the loop's output
The output processing of the loop can also be saved to a file with pipe, sort, or redirect commands.
Let's look at the example below.
#! /bin/bash
for file in /home/rich/*
do
if [ -d "$file" ]
then
echo "$file is a directory"
elif
echo "$file is a file"
fi
done > output.txt ==>The execution result of the loop is saved in the output.txt file.
Let's look at another example.
#!/bin/bash
# piping a loop to another command
for state in "North Dakota" Connecticut Illinois Alabama Tennessee
do
echo "$state is the next place to go"
done | sort
===> The processing result of the loop statement is output in alphabetical order by using
a pipe with the sort command.
echo "This completes our travels"
let's run it
$ ./test24
Alabama is the next place to go
Connecticut is the next place to go
Illinois is the next place to go
North Dakota is the next place to go
Tennessee is the next place to go
This completes our travels
$
#linux
#for
#innerloop
#outerloop
#shell
#script
'Shell Script' 카테고리의 다른 글
10 Data Expression (2) | 2022.08.13 |
---|---|
9. User data input processing (1) | 2022.08.13 |
7 Structured Command (5) | 2022.08.11 |
6. Basic Shell Script writing (3) | 2022.08.11 |
5 Linux File Permission (2) | 2022.08.11 |