S h e l l Shell Shell Scripting Language Tutorial 2 2 2
Copyright: Jingmin Wei, Pattern Recognition and Intelligent System, School of Artifical Intelligence and Automation, Huazhong University of Science and Technology
The bold and bold marks in this chapter are very important details!
This tutorial is a learning note for Shell Scripting Language and is constantly updated. Not commercially available, please contact me if you need to reprint.
Most of the screenshots are the results of my own attempts on the small black window of the Shell. Please remember to modify them according to the actual situation of your Linux system.
let, expr and (()) commands
let and (()) are interchangeable in shell programming. They allow us to write programs like C language to assign values to variable operations. It is very useful to control variable changes in loop statements.
When using let, there must be no spaces on either side of the operator. Let can parse the expression in the middle of ''
When using (()), a space is required on both sides of the operator.
(()) the value of arithmetic expression does not need to be preceded by "$" when judging if and while, but "$" when outputting echo value.
echo $(( c = a + b + 1 ))
Both let and (()) can only operate and assign values to integers.
`expr ` the use variable of $is required. let and (()) are not required at ordinary times. echo output only needs to be added at the top.
When using let or (()) assignment, expr + backquote can also be used instead (as follows, they are equivalent):
let llines=llines+fileLines llines=`expr $llines + $fileLines`
However, unlike expr, let and (()) commands do not need to add \ *.
a=1;b=2 let c=a+b # When using let, no spaces are allowed echo $c let a=11*11 (( c = a + b )) # Use (()), there must be spaces echo $c
x=12 let "x<10" echo $?
When using logical and relational operators (!, < =, > =, <, >, + +, ~ =), the shell will return a code variable, $? Will reflect whether the result is true or false. Double quotes must be used to prevent the shell from treating the greater than and less than operators as I/O redirections.
The comparison of numbers is generally used (()) instead of [[]]. Some comparison operators are not valid in [[]].
() support; Separation operation, so it is also used in the traditional for loop.
Echo & read command
For string output, more complex format control can be realized
echo string
There are two display modes: normal character display mode and normal character display mode
(the absolute path of Lenovo file. If there is no folder with spaces, you can also choose whether to use quotation marks)
echo It is a test echo "It is a test"
Escape character
echo "\"It is a test\""
The read command reads a line from standard input and assigns the value of each field of the input line to a shell variable
#!/bin/bash read name echo "$name It is a test"
Show wrap
echo -e "OK!\n" # -e enable escape, \ n wrap echo "It is a test"
Show no line breaks
echo -e "OK!\c" # -e enable escape, \ c do not wrap echo "It is a test"
Results directed to file
echo "It is a test" > testfile.txt
Use single quotation marks to output the string as it is without escaping or taking variables
echo '$name\"'
Display command execution results
echo `date`
Test code:
#!/bin/bash echo It is a test echo "It is a test" echo "\"It is a test\"" # input read name echo "$name It is a test" # Escape echo -e "OK!\n" # -e enable escape, \ n wrap echo "It is a test" echo -e "OK!\c" # -e enable escape, \ c do not wrap echo "It is a test" # Redirect to file echo "It is a test" > testfile.txt # Single quotation mark echo '$name\"' echo `date`
printf command
The printf command imitates the definition of the printf() program standard in the C library, so the script using printf is more portable than using echo.
Printf uses parameters separated by reference text or spaces. Outside, you can use formatted strings in printf. You can also specify the width and left-right alignment of strings. The default printf will not automatically add line breaks like echo. We can add them manually. \ n.
Syntax of printf command:
printf format-string [arguments...]
Parameter Description:
- Format string: format control string
- arguments: is a parameter list.
printf doesn't wrap automatically, but it doesn't need to turn on escape characters with - e like echo.
echo "Hello world!" printf "Hello world!\n"
Format output
#!/bin/bash printf "%-10s %-8s %-4s\n" name gender weight\(kg\) printf "%-10s %-8s %-4.2f\n" Weijingmin Male 53.5 printf "%-10s %-8s %-4.2f\n" Zhaoxuan Male 50.8267 printf "%-10s %-8s %-4.2f\n" Chenqin Male 55.143
%S% C% d% F are all format substitutes
%-10s refers to a character with a width of 10 characters (- indicates left alignment and no indicates right alignment). Any character will be displayed in the character with a width of 10 characters. If it is insufficient, it will be automatically filled with spaces, and if it exceeds, all the contents will be displayed.
%-4.2f refers to formatting as decimal, where. 2 refers to retaining 2 decimal places.
#!/bin/bash # Format string is a double quotation mark printf "%d %s\n" 1 "abc" # Single quotation marks have the same effect as double quotation marks printf '%d %s\n' 1 "abc" # You can output without quotation marks printf %s abcdef # The format specifies only one parameter, but the extra parameters will still be output according to the format, and the format string will be reused printf %s abc def printf "%s\n" abc def printf "%s %s %s\n" a b c d e f g h i j # If there are no arguments, by default% s is replaced with NULL and% d with 0 printf "%s and %d \n"
Escape sequence of printf
sequence | explain |
---|---|
\a | Warning character, usually ASCII BEL character |
\b | back off |
\c | Suppress (do not display) any ending newline character in the output result (valid only in the parameter string controlled by the% b format indicator), and any character left in the parameter, any subsequent parameter and any character left in the format string are ignored |
\f | Form feed |
\n | Line feed |
\r | Carriage return |
\t | Horizontal tab |
\v | vertical tab |
\ | A literal backslash character |
\ddd | A character representing a 1 to 3 digit octal value. Valid only in format strings |
\0ddd | A character representing an octal value of 1 to 3 bits |
$ printf "a string, no processing:<%s>\n" "A\nB" a string, no processing:<A\nB> $ printf "a string, no processing:<%b>\n" "A\nB" a string, no processing:<A B> $ printf "Teacher Wei \a" Teacher Wei $ # nowrap
test and [] commands
The test and [] commands are used to check whether a condition is true. They can test values, characters and files.
In the previous chapter, we have learned the use of [] in logical operation and Boolean operation, so let's look at the use of test first.
Numerical test
parameter | explain |
---|---|
-eq | Equal to true |
-ne | Not equal to true |
-gt | Greater than is true |
-ge | Greater than or equal to is true |
-lt | Less than is true |
-le | True if less than or equal to |
New test_test.sh
num1=100 num2=100 if test $[num1] -eq $[num2] then echo 'The two numbers are equal!' else echo 'The two numbers are not equal!' fi
String test
parameter | explain |
---|---|
=Or== | Equal to true |
!= | True if not equal |
-z string | True if the string length is zero |
-n string | True if string length is not zero |
test_ test. Add the following code after sh
str1="Weijingmin" str2="Weijingmin" if test str1=str2 then echo 'Two strings are equal!' else echo 'The two strings are not equal!' fi
File test
parameter | explain |
---|---|
-e file name | True if the file exists |
-r file name | True if the file exists and is readable |
-w file name | True if the file exists and is writable |
-x file name | True if the file exists and is executable |
-s file name | True if the file exists and has at least one character |
-d file name | True if the file exists and is a directory |
-f file name | True if the file exists and is a normal file |
-c file name | True if the file exists and is a character type special file |
-b file name | True if the file exists and is a block special file |
Example demonstration:
cd /bin if test -e ./bash then echo 'file already exist!' else echo 'file does not exist!' fi
In addition, Shell also provides and (- a), or (- o), non (!) Three logical operators are used to connect test conditions. Their priority is: "!" is the highest, "- a" is the second, and "- o" is the lowest. For example:
cd /bin if test -e ./notFile -o -e ./bash then echo 'A file exists!' else echo 'Neither file exists' fi
[] and test
First of all, when using [] and [[]], don't be stingy with spaces. There should be spaces on both sides of each item.
[] and test are basically the same. We talked about the use of [] in the logical operator before. Next, let's talk about the difference.
# The two are equivalent test expr1 [ expr1 ]
The effect is the same in the command line. The three basic functions of string judgment and integer judgment. Supports the use of and or not to connect expressions. Note:
The only comparison operators available in test are =, = = and! =, All three are used for string comparison and cannot be used for integer comparison. Integer comparison can be in the form of - eq, -gt.
= = and can be used in []= To compare integers and decimals.
Never use the greater than or less than sign for string comparison or integer comparison. Of course, if you really want to use it, you can use the escape form of angle brackets for string comparison. If you compare "ab" and "bc": [AB < bc], the result is true, that is, the return status is 0.
The logical operation and or not in test and [] can only use - a, - o!
#/bin/bash a="ab" if [ $a = "ab" ] then echo True else echo False fi var1=1;var2=2 if test $var1 -eq 2 -a $var2 -eq 1 then echo Equal else echo No equal fi var1=1.0;var2=2.0 if [ $var1 == 1.0 -a $var2 == 2.0 ] then echo Equal else echo No equal fi
[[]] Command
[[]] is similar to [], but it has many powerful functions.
It first supports pattern matching of strings (even shell regular expressions when using the = ~ operator).
Secondly, the logical combination in [[]] can not use - a,-o of test, but use & &, |, which is a more cordial form.
[] the symbol \ > \ < needs to be escaped because it is a command. Without escape, it will become a file redirection operation. However, as an advanced keyword, [[]] does not need command-line extension and escape.
[] can be used as arithmetic extension, but [] cannot.
When comparing strings, the string on the right can be used as a pattern (this is when the string on the right is not double quoted. If the string on the right is double quoted, it is considered to be a text string), Not just a string, such as [[Hello = = shell?]], The result is true.
Common regular expressions can be seen in Python and Java. expression
[ ] | [[ ]] | |
---|---|---|
Digital test | -eq -ne -lt -le -gt -ge | Same as [] |
File test | -r -l -w -x -f -d -s -nt -ot | Same as [] |
Character test | = != - n -z = = (same as =) \ < \ > cannot be used > =<= | Same as [], but > < no escape is required |
Logic test | -a -o ! (no logic short circuit) | && || ! (observe logic short circuit) |
Mathematical operation | Not available | + - * / % |
expression# pattern matching [[ $a == z* ]] # If $a starts with "z" (pattern matching), it will be true [[$a == "z*" ]] # If $a equals z * (character matching), the result is true [ $a == "z*" ] [ $a == z* ] # The effect is the same. If $a equals z * (character matching), the result is true
if [ "$a" != "$b" ] # != Not equal to, this operator will use pattern matching in the [[]] structure
# Less than, in ASCII alphabetical order For example: if [[ "$a" < "$b" ]] if [ "$a" \< "$b" ] # "<" in [] structure needs to be escaped
For the comparison of character expressions, the test of file expressions and the test of logical expressions, it is best to use [[]].
If then - elif then - else - fi
Note that the process control of sh cannot be empty, that is, if there is no statement execution in the else branch, do not write this else.
if statement syntax format:
if condition then command1 command2 ... commandN fi
Write in one line (for terminal command prompt):
ps -ef | grep is used to check whether the service is started
if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi
fi at the end is if, which is spelled upside down. Similar problems will be encountered later.
if else syntax format:
if condition then command1 command2 ... commandN else command fi
If else if else syntax format:
if condition1 then command1 elif condition2 then command2 else commandN fi
The if else statement is often used in combination with the test command, as shown below:
#!/bin/bash num1=$[2*3] num2=$[1+5] if test $[num1] -eq $[num2] then echo 'Two numbers are equal' else echo 'Two numbers are unequal' fi
For... in... - do - done and for ((;))
The general format of for loop is:
for var in item1 item2 ... itemN do command1 command2 ... commandN done
Write in one line:
for var in item1 item2 ... itemN; do command1; command2... done;
When the variable value is in the list, the for loop executes all commands once and uses the variable name to obtain the current value in the list. The command can be any valid shell command and statement. The in list can contain substitutions, strings, and file names.
The in list is optional. If it is not used, the for loop uses the positional parameter of the command line.
For example, sequentially output the numbers in the current list:
for i in 1 2 3 4 5 do echo "The value is: $i" done
Array traversal
array=(1 2 3 4 5) # Standard cycle using (()) for (( i=0; i<${#array[@]}; i++ )); do echo "The value is: ${array[i]}" done # Without subscript loop, in essence, it lists all elements of the array and takes values one by one for i in ${array[@]}; do echo "The value is: $i" done # Subscript loop for i in "${!array[@]}"; do printf "%d\t" "${array[i]}" done
Character traversal
for chr in 'This is a string' do echo $chr done
while - do - done
The while loop is used to continuously execute a series of commands and read data from the input file; Commands are usually test conditions. The format is:
while condition do command done
The following is a basic while loop. The test condition is that if int is less than or equal to 5, the condition returns true. Int starts from 0. In each cycle, int adds 1. Run the above script, return the numbers 1 to 5, and then terminate.
#!/bin/bash int=1 while(( $int <= 5 )) do echo $int let int++ done
The while loop can be used to read keyboard information. In the following example, the input information is set to the variable FILM, and press Ctrl-D to end the loop.
echo -n 'Enter the name of your favorite movie: ' while read FILM do echo "yes! $FILM It's a good movie" done
Infinite loop
Format:
while : do command done while true do command done for (( ; ; ))
until - do - done
The until loop executes a series of commands until the condition is true.
until loop enters the loop only when the condition is not established, and exits when the condition is established. The processing method is just the opposite to that of while loop.
while loops are generally better than until loops, but in some cases - and only in rare cases - until loops are more useful.
until syntax format:
until condition do command done
The condition can be any test condition. The test occurs at the end of the loop, so the loop is executed at least once.
Calculate the sum of 1-100
#!/bin/bash tmp=0 until (( tmp >= 100 )) do let tmp++ let result+=tmp done echo "result=$result"[External chain picture transfer failed,The origin station may have anti-theft chain mechanism,It is recommended to save the picture and upload it directly(img-15rANjCs-1646710889639)(/home/weijingmin/picture/2022-01-29 19-32-52 Screenshot of.png)]
case ... in - 1) ;; 2) ;; 3) ;; - esac
case value in Mode 1) command1 command2 ... commandN ;; Mode 2) command1 command2 ... commandN ;; esac
case works as shown above. The first mock exam must be the word in, and each pattern must end with the right parenthesis. Values can be variables or constants. After matching, the first mock exam is executed until all values are in accordance with a certain pattern.
The value will detect each matching pattern. Once the pattern matches, the corresponding command of matching pattern will be executed, and other patterns will not be continued. If there is no matching pattern, use the asterisk * to capture the value, and then execute the following command.
The following script prompts you to enter 1 to 4 to match each pattern:
#!/bin/bash echo 'please input a number:' read num case $num in 1) echo 'you input 1' ;; 2) echo 'you input 2' ;; 3) echo 'you input 3' ;; *) echo 'the number you input is not range from 1 to 3' ;; esac
Input different content, there will be different results.
Jump out of loop
In the process of loop, sometimes it is necessary to forcibly jump out of the loop when the loop end condition is not reached. The Shell uses two commands to realize this function: break and continue.
break
The break command allows you to jump out of all loops (terminate the execution of all subsequent loops).
In the following example, the script enters an endless loop until the user enters a number greater than 5. To jump out of this loop and return to the shell prompt, you need to use the break command.
#!/bin/bash while : do read num case $num in 1|2|3|4|5) echo "the number ${num} is range from 1 to 5" ;; *) echo "game over" break ;; esac done
continue
The continue command does not jump out of all loops, only the current loop wheel.
#!/bin/bash while : do echo 'please input a number: ' read num case $num in 1|2|3|4|5) echo "the number ${num} is range from 1 to 5" ;; *) continue echo "game over" ;; esac done
When a number greater than 5 is entered, the loop in this example will not end and the statement echo "game over" will never be executed.