In the daily system management work, the need to write scripts to complete specific functions, writing shell scripts is a basic skill!
In the process of writing, master some common skills and grammar can do most of the functions, that is, 2/8 principles
1. The difference between single and double quotation marks
The biggest difference between single and double quotes is that the double quotation marks can still refer to the contents of the variable, but only ordinary characters in the single quotation mark, not as a reference to the variable, directly output character channeling. Consider the following example:
[Email protected] ~]# Name=haha
[Email protected] ~]# echo $name
HaHa
[Email protected] ~]# myname= "$name is wow"
[Email protected] ~]# echo $myname
HaHa is Wow
[[email protected] ~]# myname= ' $name is wow '
[Email protected] ~]# echo $myname
$name is Wow
As can be seen from the above example, the use of single quotation marks, then $name is only ordinary characters, direct output!
2. Progressive reading of files
Note: Because the use for to read in the file line, will automatically put the space and newline characters as the same delimiter, if there are spaces in the line, the output will be very messy, so only for the row can not have spaces or newline characters of the file
Note: Because a while is used to read a row in a file, it reads the entire line, does not focus on the contents of the line (space ...), so it is preferable for a for-read file, and it is recommended to use the while loop to read the file
3. Common implied variables in bash shell scripts
$ |
The currently executing script or command name |
$1-$9 |
Represents the position of the parameter. For example, the first parameter is represented. |
$# |
Number of arguments called by the script |
[Email protected] |
The contents of all parameters |
$* |
The contents of all parameters |
$$ |
The process number of the currently running script |
$? |
Status returned after the command executes |
$! |
The last process number running in the background |
Note: $? Used to check that the last command was executed correctly (in Linux, the command exit status is 0 to indicate that the command executes correctly, and any non-0 value indicates a command error)
The most common use of $$ variables is to name the staging file to ensure that the staging file is not duplicated.
$* and [email protected] If the output is the same, but when using a for loop, "$*" is output as an element when using double quotation marks ("") and "[email protected]" is output as an element per parameter
See test examples
#cat test.sh
#!/bin/sh
Echo ' [email protected] ' output ... '
For i in "[email protected]"
Do
Echo $i
Done
Echo ' "$*" output .... '
For i in "$*"
Do
Echo $i
Done
Output results
#sh test.sh a b c D
"[Email protected]" output .....
A
B
C
D
"$*" Output ....
A B c D
from the output can be seen "$*" output is a row and "[email protected]" Output is four rows
4. Deletion and substitution of variable contents
In some cases, we need to find and delete or replace the characters in the variable, and we need to use the methods listed in the following table.
Variable Setting method |
Description |
${variable # keyword} |
If the contents of the variable content start from scratch conform to ' keyword ', then the minimum data will be deleted. |
${variable # #关键字} |
If the contents of the variable content start from scratch conform to ' keyword ', the maximum data will be deleted |
${Variable% keyword} |
If the contents of the variable from the tail forward data conform to the ' keyword ', then the minimum data will be deleted |
${Variable% keyword} |
If the contents of the variable from the tail forward data conform to the ' keyword ', then the maximum data that will be met is deleted |
${variable/old string/new string} |
If the variable content matches the ' old string ' then ' the first old string will be replaced with the new string |
${variable//old string/new string} |
If the variable content matches the ' old string ' then ' all old strings will be replaced by the new string |
For example, remove a character from a character channeling:
[Email protected] ~]# export test_str= "/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin :/bin:/usr/sbin:/usr/bin:/root/bin "
[Email protected] ~]# echo ${test_str#/*kerberos/bin:}
/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
5. Variable Condition test Assignment
At some point we need to ' judge ' whether a variable exists, assign the value of the variable to a new variable if it exists, and assign the other value to the new variable if the variable does not exist.
Variable Setting method |
str Not defined |
str is empty string |
STR is assigned a non-empty string |
VAR=${STR-EXPR} |
var=expr |
Var= |
Var= $str |
VAR=${STR:-EXPR} |
var=expr |
var=expr |
Var= $str |
VAR=${STR+EXPR} |
Var= |
var=expr |
var=expr |
VAR=${STR:+EXPR} |
Var= |
Var= |
var=expr |
VAR=${STR?EXPR} |
Expr output to stderr |
Var= |
Var= $str |
VAR=${STR:?EXPR} |
Expr output to stderr |
Expr output to stderr |
Var= $str |
VAR=${STR=EXPR} |
var=expr |
Var= |
Var= $str |
VAR=${STR:=EXPR} |
var=expr |
var=expr |
Var= $str |
Examples are as follows:
[[email protected] ~]# test_name= ""
[[email protected] ~]# Test_name=${test_name-root}
[Email protected] ~]# echo $test _name
<== because Test_name is set to the empty character channeling! So of course still reserved for the empty character channeling!
[[email protected] ~]# Test_name=${test_name:-root}
[Email protected] ~]# echo $test _name
Root <== Plus ': ' After the variable content is empty or not set, can be replaced with the following content!
basically the test of this variable can also be done through the if...then in the shell script ... , but the simple method mentioned above to test the variables is that the program looks more streamlined!
6. Shell separator: Variable IFS use
In a shell script, if you use a For loop character channeling, the default is to use a space to split the character channeling. As mentioned earlier, when you use a For loop to read the contents of a file row by line, the output will become chaotic if there are spaces in the file line. This time use IFS variables to set specific character channeling To achieve the correct output. By default IFS is used, space \ t \ n to be the default separator.
We will be able to output the correct example of the previous use of the for line reading of the file, see below
#!/bin/bash
ifs_old= $IFS #将原IFS值保存 in order to recover after use
ifs=$ ' \ n ' #更改IFS值为 $ ' \ n '
For line in ' cat file.txt '
Do
Echo $line
Done
File.txt file contents are as follows
[Email protected]]$ cat file.txt
Sdfsdfsdfsdf
Ssssss ssssss ssssss sssss
Sdfsdfsdfsdfsdf
Execute the test program output as follows (correct output)
[Email protected]]$ sh test.sh
Sdfsdfsdfsdf
Ssssss ssssss ssssss sssss
Sdfsdfsdfsdfsdf
If the IFS variable is not set, the default IFS variable value is used, and the output is as follows
[Email protected]]$ sh test.sh
Sdfsdfsdfsdf
Ssssss
Ssssss
Ssssss
Sssss
Sdfsdfsdfsdfsdf
From the above test program output results, can be based on their own needs to set the IFS variable, in an example is as follows:
While ifs=: Read UserName passWord userID groupID geCos homedir Usershell
Do
echo "$userName $homeDir"
Done </etc/passwd
7. Use of shell arrays
Array Assignment Method:
(1) array= (var1 var2 var3 ... varn)
(2) array= ([0]=VAR1 [1]=var2] [2]=var3 ... [N]=varn]
(3) Array[0]=var1
Arrya[1]=var2
...
Array[n]=varn
To calculate the number or length of an array element:
(1) ${#array [@]}
(2) ${#array [*]}
Understanding the array base syntax, for example, see:
#!/bin/bash
Nameservers= ("ns1.www.net.") "Ns2.www.net." "Ns3.www.net.")
# Get Array length
tlen=${#NAMESERVERS [@]}
# Loop Array
for ((i=0; i<${tlen}; i++));
Do
echo ${nameservers[$i]}
Done
Looking at a more complex example, read the contents of the file into the array:
#!/bin/bash
# Set IFS to set the delimiter to line feed (\ n)
oldifs= $IFS
ifs=$ ' \ n '
# Read the contents of the file into an array
Filearray= ($ (cat file.txt))
# Restore it
ifs= $OLDIFS
tlen=${#fileArray [@]}
# Cycle through file contents
for ((i=0; i<${tlen}; i++));
Do
echo "${filearray[$i]}"
Done
8. Logic Judgment Condition Test
- Determining the properties of a file
operator |
Test Results |
-e filename |
File exists return 1, otherwise return 0 |
-R filename |
The file can be read back 1, otherwise 0 is returned |
-W filename |
The file can be written back 1, otherwise return 0 |
-X filename |
File executable returns 1, otherwise returns 0 |
-O filename |
The file belongs to the user himself returns 1, otherwise returns 0 |
-Z filename |
File length is 0 returns 1, otherwise 0 |
-F filename |
File returns 1 for normal file, otherwise returns 0 |
-D filename |
Returns 1 if the file is a directory file, otherwise returns 0 |
For example, test whether a file exists:
#!/bin/bash
echo "Checks the existence of the messages file."
Echo-n "Checking ..."
if [-f/var/log/messages];then
echo "/var/log/messages exists."
Fi
Echo
echo "... done."
operator |
Compare Results |
STR1 = str2 |
True when two strings are equal |
Str1! = str2 |
True when two strings are not equal |
-N str1 |
True when the length of a string is greater than 0 |
-Z str1 |
True when the length of a string is 0 |
Str |
True when the string is non-empty |
As an example, compare strings to test the user id:
If ["$ (whoami)"! = ' root ']; Then
echo "You had no permission to run $ as Non-root user."
Exit 1;
Fi
- Numeric comparison (integer)
operator |
Compare Results |
Num1-eq num2 |
Two numbers equal to True |
Num1-ne num2 |
Two numbers are true. |
NUM1-GT num2 |
NUM1 greater than num2 is true |
Num1-ge num2 |
NUM1 greater than or equal to num2 true |
Num1-lt num2 |
NUM1 less than num2 is true |
Num1-le num2 |
NUM1 less than or equal to num2 true |
Examples are as follows:
num= ' Wc-l work.txt '
If [$num-gt];then
echo "You" ve worked hard enough for today. "
Echo
Fi
If you want to view detailed test actions, you can view the man manual man test
Summary of common methods of bash shell scripting in System management