Detailed explanation of shell script programming for front end

Fang Xu 2020-11-11 12:36:23
detailed explanation shell script programming


My blog original link :https://chenfangxu.lap.360.cn/assistive-tools/shell/script.html


Shell Script (shell script), It's for Shell Write the script , The general file suffix is .sh.

Script interpreter

#! It's an agreed mark , It tells the system what interpreter the script needs to run , That is, what kind of shell.#! go by the name of shebang( Also known as Hashbang), For example, using bash:#! /bin/bash

Create a new one test.sh The file of , The contents are as follows :

#!/bin/bash
echo "Hello World!"

function Shell Script

The first way : As an executable

1、 At present test.sh There are no executable permissions , First, make the script file have execute permission .

# Make the script file have execute permission
chmod +x ./test.sh

2、 Execute the script

# Execute the script , It should be noted that the directory should be marked
./test.sh
# It can also be used. source To execute the script , It's equivalent to the above , But you don't need the script to have execution rights
source ./test.sh

Be careful : It must be written as ./test/sh , instead of test.sh . It's the same with other binary programs , direct writing test.sh,Linux The system will go to PATH I'm looking for a call test.sh Of , And only /bin, /sbin, /usr/bin, /usr/sbin Wait in PATH in . Your current directory is usually not in PATH in , So it's written as test.sh There's no command , Use ./test.sh Tell the system , Look for... In the current directory .

Run... In this way bash Script , The first line must be correct , So that the system (Shell Program ) Find the right interpreter . If you use the standard default shell, You can leave out the first line .

As interpreter parameters

Run the interpreter directly , The parameter is Shell The filename of the script .

/bin/bash test.sh

Scripts that run this way , You don't need to specify interpreter information on the first line , It's no use writing .

grammar

1、 notes

  • Single-line comments : With # start , To end of line .
  • Multiline comment : With :<<EOF start , To EOF end
# This is a single line comment
:<<EOF
This is a multiline comment
This is a multiline comment
EOF

If there is a piece of code to comment and uncomment frequently , It can be enclosed in curly brackets , Defined as a function , There's no place to call this function , This code will not execute , Achieved the same effect as annotation .

2、 Variable

Variable type

  • local variable : Local variables are variables that are only valid within a script . They can't be accessed by other programs and scripts .
  • environment variable : Environment variables are variables inherited from the parent process , For the current Shell All programs and scripts in the session are visible . Creating them is similar to creating local variables , But it uses export keyword ,shell Scripts can also define environment variables .
  • shell Variable ( System variables ):shell Variables are derived from shell Special variables for program settings .shell Some of the variables are environment variables , Some of them are local variables , These variables guarantee shell Normal operation of .

Variable Syntax

1、 Declare variables

You can use the equal sign operator to assign values to variables :varName=value,varName Is a variable name. ,value Is the value assigned to a variable .

Naming rules for variable names :

  • The first letter must be a letter (a-z,A-Z), The rest is in English letters only , Number underline
  • No spaces in between , You can use underscores , If there are spaces , You must use single or double quotation marks
  • You can't use punctuation
  • Out of commission shell keyword
#!/bin/bash
fruit=apple
count=5

Be careful :varName=value There are no spaces on either side of the equal sign of , If there is a space in the variable value , It needs to be enclosed in quotation marks .

2、 Access variables

The syntax of accessing variables is :${varName} and $varName, Curly braces outside variable names are optional , Add it or not , Curly braces are used to help the interpreter identify the boundaries of variables ( Curly brackets are recommended ).

#!/bin/bash
fruit=apple
count=5
echo "We have $count ${fruit}s"
# Output :We have 5 apples

because Shell Use white space to separate words , So in the above example, we need to add curly brackets to tell Shell The variable name here is fruit, instead of fruits

Be careful : When using single quotation marks , Variables are not expanded (expand), Still as it is . It means echo '$var' Will be displayed \$var. When using double quotes , If \$var It has been defined , that echo "$var" The value of the variable will be displayed , If there is no definition , Then nothing is shown .

3、 A read-only variable

Use readonly Commands can define variables as read-only variables , The value of a read-only variable cannot be changed

#!/bin/bash
fruit=apple
echo $fruit
readonly fruit
#fruit=banana # If you let go of the comments , Error will be reported during execution 

4、 Delete variables

Use unset Command to delete variables , Variable cannot be used again after being deleted .unset Command cannot delete read-only variables

#!/bin/bash
fruit=apple
echo $fruit
# Output : apple
unset fruit
echo $fruit
# Output : ( empty )

Shell Special variables ( System variables )

The naming rules for variable names have been mentioned above , But there are also variables that contain other characters that have special meanings , Such variables are called special variables .

Variable meaning
$0 File name of the current script
$n Parameters passed to a script or function .n It's a number , Indicates the number of parameters . for example , The first parameter is \$1
$# Number of arguments passed to script or function
$* All parameters passed to a script or function
$@ All parameters passed to a script or function , By double quotes ("") Inclusion time , And \$\* not quite the same
$FUNCNAME The name of the function ( Only in functions )
$? Exit status of last command , Or the return value of a function
$- Show shell Current options used (flag), In the later extension, we will use
$$ At present Shell process ID. about Shell Script , It's the process of these scripts ID
$! The last process running in the background ID Number
Command line arguments : The parameters passed to the script at run time become parameters to the script , Command line parameters use $n Express .
#!/bin/bash
# ./test.sh
echo " file name :$0"
echo " The first command line argument :$1"
echo " The second command line argument :$2"
echo " All parameters passed in :$@"
echo " All parameters passed in :$*"
echo " The number of all parameters :$#"

Carry out orders :./test.sh Linux Shell, The result is :

 file name :./test.sh
The first command line argument :Linux
The second command line argument :Shell
All parameters passed in :Linux Shell
All parameters passed in :Linux Shell
The number of all parameters :2

$? You can get the exit status of the previous command . So called exit status , Is the result of the last command . Exit status is a number , In general , Most commands are executed successfully and will return 0, Failure will return 1.$? It can also represent the return value of a function .

3、 character string

String quotes

shell Strings can use single quotes '' , You can also use double quotes "" , You can also use no quotes .

  • Single quotation marks : Don't recognize variables , Single quotation marks cannot appear in the middle of single quotation marks ( It doesn't work with escape characters ), Can appear in pairs to achieve string splicing .
name='world'
before='hello,'${name}'!' # Use single quotation marks to concatenate strings
after='hello,${name}!' # Variables in single quotation marks do not parse
echo ${before}_${after}
# Output :hello,world!_hello,${name}!
  • Double quotes : You can identify variables , Double quotation marks that are escaped with the escape character can appear in double quotation marks
name="\"shell\"" # Escaped double quotation marks are allowed within double quotation marks
before="hello,"${name}"!" # Use double quotation marks to concatenate strings
after="hello,${name}!" # Variables in double quotes will parse
echo ${before}_${after}
# Output :hello,"shell"!_hello,"shell"!
Set a string variable , The following are all operations on this variable
file=/dir1/dir2/dir3/my.file.txt

${#var}: Get the length of the variable value

echo ${#file}
# Output :27

${varx}: The substring is intercepted by the index position

echo ${file:0:5} # Intercept the leftmost 5 Characters
# Output :/dir1
echo ${file:5:5} # From 6 Character start , Intercept 5 Characters
# Output :/dir2

${var#}、${var##}: Delete the value to the left of the string

echo ${file#*/} # Delete the first / And the string to the left of it
# Output :dir1/dir2/dir3/my.file.txt
echo ${file##*/} # Delete the last one / And the string to the left of it
# Output :my.file.txt
echo ${file#*.} # Delete the first . And the string to the left of it
# Output :file.txt
echo ${file##*.} # Delete the last one . And the string to the left of it
# Output :txt

${var%}、${var%%}: Delete the value to the right of the string

echo ${file%/*} # Delete the last one / And the string to the right of it
# Output :/dir1/dir2/dir3
echo ${file%%/*} # Delete the first / And the string to the right of it
# Output :( Null value )
echo ${file%.*} # Delete the last one . And the string to the right of it
# Output :/dir1/dir2/dir3/my.file
echo ${file%%.*} # Delete the first . And the string to the right of it
# Output :/dir1/dir2/dir3/my

${var:-word}: If the variable var It's empty 、 Not defined or deleted (unset), Then the return word, But it doesn't change. var Value .

echo ${var:-"var is not set"}
# Output :var is not set
echo "var is ${var}"
# here var Still no definition , So the output :var is

${var:=word}: If the variable var It's empty 、 Not defined or deleted , Then the return word, And will var Is set to word.

echo ${var:="var is not set"}
# Output :var is not set
echo "var is ${var}"
# here var Has been defined as var is not set 了 , So the output :var is var is not set

${var:?message}: If the variable var It's empty 、 Not defined or deleted , Then send the message message Send to standard error output .

Can be used to detect variables var Whether it can be assigned normally . If this substitution appears in shell Script , Then the script will stop running .

${var:+word}: If the variable var Defined , Then the return word, But it doesn't change. var Value .

Array

An array is a variable that can store multiple values , These values can be referenced individually , It can also be referenced as an entire array . Array subscript from 0 Start , The subscript can be an integer or an arithmetic expression , Its value should be greater than or equal to 0.

Create array

numbers=(one two three four five)
# When creating an array, indicate the subscript
colors=([1]=red [0]=yello [2]=blue)

Access array

Access individual elements

echo ${numbers[2]}
# Output :three

Access all elements of the array

echo ${colors[*]}
# Output :yello red blue
echo ${colors[@]}
# Output :yello red blue

${colors[*]} and ${colors[@]} There are subtle differences , When you output each element in an array on a separate line , Whether it's enclosed in quotation marks makes a difference , In quotation marks ,${colors[@]} Expand each element in the array to a single parameter , Spaces in array elements are preserved .

Accessing partial elements of array

# :0:2 Remove the array from 0 Start , The length is 2 Array elements of
echo ${colors[@]:0:2}
# Output :yello red

Length of array

echo ${#colors[@]}
# Output :3

Adding elements to an array

colors=(white "${colors[@]}" green black)
echo ${colors[@]}
# Output :white yello red blue green black
echo ${#colors[@]}
# Output :6

Delete elements from array

unset colors[2]
echo ${colors[@]}
# Output :white yello blue green black
echo ${#colors[@]}
# Output :5

A complete code example :

#!/bin/bash
numbers=(one two three four five)
colors=([1]=red [0]=yello [2]=blue)
echo ${numbers[2]}
echo ${colors[*]}
echo ${colors[@]}
echo ${colors[@]:0:2}
echo ${#colors[@]}
colors=(white "${colors[@]}" green black)
echo ${colors[@]}
echo ${#colors[@]}
unset colors[2]
echo ${colors[@]}
echo ${#colors[@]}

Operator

Shell There are many operators in , Including arithmetic operators 、 Relational operator 、 Boolean operator 、 String operators and file testers .

Arithmetic operator

Native bash Simple mathematical operations are not supported , It is more commonly used with the help of expr To implement mathematical operations .

List of arithmetic operators , Variable a yes 10 Variable b yes 50

Operator explain give an example
+ Add expr ${a} + ${b} The result is 60
- Subtraction expr ${b} - ${a} The result is 40
\* Multiplication expr ${a} \\* ${b} The result is 500
/ division expr ${b} / ${a} The result is 5
% Remainder expr ${b} % ${a} The result is 0
= assignment a=$b It's a normal variable assignment

The sample code is as follows :

#!/bin/bash
a=10
b=50
value=`expr ${a} + ${b}`
echo "a + b = ${value}"
value=`expr ${b} - ${a}`
echo "b - a = ${value}"
value=`expr ${a} \* ${b}`
echo "a * b = ${value}"
value=`expr ${b} / ${a}`
echo "b / a = ${value}"
value=`expr ${b} % ${a}`
echo "b % a = ${value}"
# Output
#a + b = 60
#b - a = 40
#a * b = 500
#b / a = 5
#b % a = 0

Be careful :

  1. Space between expression and operator , for example 1+1 It's wrong. , Must be written as 1 + 1
  2. The complete expression should be in back quotation marks ` encase
  3. Conditional expressions should be placed between square brackets , And there should be spaces , for example [${a}==${b}] It's wrong. , Must be written as [ ${a} == ${b} ]

Conditional operator ( Relational operator )

Relational operators only support numbers , String not supported , Unless the value of the string is a number .

List of relational operators , Variable a yes 10 Variable b yes 50

Operator explain give an example
-eq Check whether two numbers are equal , Equal return true [ ${a} -eq ${b} ] return false
-ne Check if two numbers are not equal , Unequal return true [ ${a} -ne ${b} ] return true
-gt Check whether the number on the left is greater than the number on the right , If it is , return true [ ${a} -gt ${b} ] return false
> Follow -gt equally , But because of compatibility issues , May be in [[]] Use in expressions [[ ${a} > ${b} ]] return false
-lt Check whether the number on the left is less than the number on the right , If it is , return true [ ${a} -lt ${b} ] return true
< Follow -lt equally , But because of compatibility issues , May be in [[]] Use in expressions [[ ${a} < ${b} ]] return true
-ge Check whether the number on the left is greater than or equal to the number on the right , If it is , return true [ ${a} -ge ${b} ] return false
-le Checks whether the number on the left is less than or equal to the number on the right , If it is , return true [ ${a} -le ${b} ] return true

The example code is as follows :

!/bin/bash
a=10
b=50
if [ ${a} -eq ${b} ]; then
echo "${a} -eq ${b} : a be equal to b"
else
echo "${a} -eq ${b} : a It's not equal to b"
fi
# Output :10 -eq 50 : a It's not equal to b
if [ ${a} -ne ${b} ]; then
echo "${a} -ne ${b} : a It's not equal to b"
else
echo "${a} -ne ${b} : a be equal to b"
fi
# Output :10 -ne 50 : a It's not equal to b
if [ ${a} -gt ${b} ]; then
echo "${a} -gt ${b} : a Greater than b"
else
echo "${a} -gt ${b} : a Less than b"
fi
# Output :10 -gt 50 : a Less than b
if [[ ${a} > ${b} ]]; then
echo "${a} > ${b} : a Greater than b"
else
echo "${a} > ${b} : a Less than b"
fi
# Output :10 > 50 : a Less than b
if [ ${a} -lt ${b} ]; then
echo "${a} -lt ${b} : a Less than b"
else
echo "${a} -lt ${b} : a Greater than b"
fi
# Output :10 -lt 50 : a Less than b
if [[ ${a} < ${b} ]]; then
echo "${a} < ${b} : a Less than b"
else
echo "${a} < ${b} : a Greater than b"
fi
# Output :10 < 50 : a Less than b
if [ ${a} -ge ${b} ]; then
echo "${a} -ge ${b} : a Greater than or equal to b"
else
echo "${a} -ge ${b} : a Less than or equal to b"
fi
# Output :10 -ge 50 : a Less than or equal to b
if [ ${a} -le ${b} ]; then
echo "${a} -le ${b} : a Less than or equal to b"
else
echo "${a} -le ${b} : a Greater than or equal to b"
fi
# Output :10 -le 50 : a Less than or equal to b

Conditional operator ( Boolean operator 、 Logical operators 、 String operators )

List of conditional operators , Variable a yes 10, Variable b yes 50, Variable x yes "abc", Variable y yes "efg"

Operator explain give an example
! Non operation [ ! false ] return true
-o Or operations [ ${a} -eq 10 -o ${b} -eq 100 ] return true
-a And operation [ ${a} -eq 10 -a ${b} -eq 50 ] return true
&& Follow -a similar , Logical AND, But you need to use [[]] expression [[ ${a} -eq 10 && ${b} -eq 50 ]] return true
= Check whether two numbers or strings are equal , Equal return true [ ${a} = ${b} ] return false
!= Check whether two numbers or strings are equal , Unequal return true [ ${a} != ${b} ] return true
== equal . Compare two numbers or strings , If equal returns true( It is not recommended to use , Compatibility issues ) [ ${a} == ${b} ] return false
-z Check if the string length is 0, by 0 return true [ -z ${x} ] return false
-n Check if the string length is 0, Not for 0 return true [ -n ${x} ] return true
var Check whether the variable exists or is not empty , Exist or not empty return true [ $s ] return false

The code example is as follows :

#!/bin/bash
a=10
b=50
x="abc"
y="edf"
# single []
if [ ${a} -eq 10 -a ${b} -eq 50 ]; then
echo "${a} -eq 10 -a ${b} -eq 50 : return true"
else
echo "${a} -eq 10 -a ${b} -eq 50 : return false"
fi
# Output :10 -eq 10 -a 50 -eq 50 : return true
# double []
if [[ ${a} -eq 10 && ${b} -eq 50 ]]; then
echo "${a} -eq 10 && ${b} -eq 50 : return true"
else
echo "${a} -eq 10 && ${b} -eq 50 : return false"
fi
# Output :10 -eq 10 && 50 -eq 50 : return true
if [ ${a} = ${b} ]
then
echo "a and b equal "
fi
if [ ${a} != ${b} ]
then
echo "a and b It's not equal "
fi
#a and b It's not equal
if [ -z ${x} ]; then
echo "-z ${x}: String length is 0 "
else
echo "-z ${x}: String length is not 0 "
fi
# Output :-z abc: String length is not 0
if [ -n ${y} ]; then
echo "-z ${y}: String length is not 0 "
else
echo "-z ${y}: String length is 0 "
fi
# Output :-z edf: String length is not 0
if [ $x ];then
echo "${x}: Not an empty string "
else
echo "${x}: Is an empty string "
fi
# Output :abc: Not an empty string
if [ $s ];then
echo '${s}: There is '
else
echo '${s}: non-existent '
fi
# Output :${s}: non-existent

File directory judgment operator

File directory judgment operator list

Operator explain
-f filename Judge whether the file exists , When filename When it exists and is a regular document ( It's not a catalog , It's not a device file ) return true
-d pathname Determine whether the directory exists , When pathname When it exists and returns a directory true
-e pathname Judge 【 Something 】 Whether there is , When pathname Returns when the specified file or directory exists true
-a pathname ditto , Outdated , And there's another logic to use with , Easy to confuse
-s filename Determine whether it is a non empty file , When filename Exists and the file size is greater than 0 When to return to true
-r pathname Judge whether it is readable , When pathname Returns when the specified file or directory exists and is readable true
-x pathname To judge whether or not to execute , When pathname Returns when the specified file or directory exists and is executable true
-w pathname Judge whether it is writable , When pathname Returns when the specified file or directory exists and is writable true
-b filename Determine whether it is a block file , When filename Returns when a block file exists true
-c filename Determine whether it is a character file , When filename When there is a character file, return true
-L filename Determine whether it is a symbolic link , When filename Return when there is a symbolic link true
-u filename Determine whether the file is set SUID position ,SUID yes Set User ID
-g filename Determine whether the file is set SGID position ,SGID yes Set Group ID

The sample code is as follows :

#!/bin/bash
file="/etc/hosts"
if [ -f ${file} ]; then
echo "${file}: It's a common document "
else
echo "${file}: It's not a normal file "
fi
# Output :/etc/hosts: It's a common document
if [ -d ${file} ]; then
echo "${file}: It's a catalog "
else
echo "${file}: Not a directory "
fi
# Output :/etc/hosts: Not a directory
if [ -e ${file} ]; then
echo "${file}: File exists "
else
echo "${file}: file does not exist "
fi
# Output :/etc/hosts: File exists
if [ -s ${file} ]; then
echo "${file}: The file is not empty "
else
echo "${file}: The file is empty "
fi
# Output :/etc/hosts: The file is not empty
if [ -r ${file} ]; then
echo "${file}: Documents are readable "
else
echo "${file}: The file is unreadable "
fi
# Output :/etc/hosts: Documents are readable 

Conditional statements

In a conditional statement , from [] or [[]] The wrapped expression is called Test command or Primitives .

if...fi sentence

 grammar :
if [ expression ]
then
expression yes true , It's going to be enforced here
fi
#!/bin/bash
if [ 1 = 1 ]
then
echo " equal "
fi
# Output : equal
# It can also be written in a line
if [ "a" = "a" ]; then echo " equal "; fi
# Output : equal 

if...else Often follow test Command in combination with ,test The command is used to check if a condition holds , And square brackets [] similar ( The two of them are in /usr/bin It is pointed to by soft link ).

#!/bin/bash
a=10
b=50
if test ${a} -eq ${b}
then
echo "a be equal to b"
else
echo "a It's not equal to b"
fi
# Output :a It's not equal to b

if...else...fi

 grammar :
if [ expression ]
then
expression yes true , It's going to be enforced here
else
expression yes false , It's going to be enforced here
fi
#!/bin/bash
if [ 1 = 2 ]
then
echo " equal "
else
echo " It's not equal "
fi
# Output : It's not equal 

if...elif...fi

 grammar :
if [ expression1 ]
then
expression yes true , It's going to be enforced here
elif [ expression2 ]
then
expression1 yes true , It's going to be enforced here
else
above expression All are false , It's going to be enforced here
fi
#!/bin/bash
a=10
b=50
if [ ${a} -eq ${b} ]
then
echo "a be equal to b"
elif [ ${a} -gt ${b} ]
then
echo "a Greater than b"
else
echo "a Less than b"
fi
# Output :a Less than b

case...esac

case...esac And in other languages switch...case similar , It's a multi branch selection structure .

case Statement matches a value or a pattern , If the match is successful , Execute the command you want to match . Applicable to many situations that need to be faced with , Different measures should be taken separately .

case value in
Pattern 1)
command1
command2
command3
;;
Pattern 2)
command1
command2
command3
;;
*)
command1
command2
command3
;;
esac
#!/bin/bash
echo " Input 1-4 A number of "
echo " The number you entered is :"
read number
case $number in
1)
echo " You entered 1"
;;
2)
echo " You entered 2"
;;
3)
echo " You entered 3"
;;
4)
echo " You entered 4"
;;
*)
echo " What you input is not 1-4 The number of "
;;
esac
# After running, you can input digital experience by yourself 

Be careful : Can be in ) Pre use | Split multiple patterns .

Loop statement

bash There are four cycles in :for , while , until , select

for loop

 grammar :
for Variable in list
do
command1
command2
...
commandN
done

A list in syntax is a set of values ( Numbers 、 character string ) The sequence of components , Each value is separated by a space . These values can also be wildcards or braces extensions , for example *.sh and {1..5}.

#!/bin/bash
for i in 1 2 3 4 5
do
echo $i
done
# Write in a line
for i in {1..5}; do echo $i ; done

while loop

while The loop will constantly detect a condition , As long as this condition returns true, Just execute a command . The conditions to be tested are the same as if The same as in China .while It can also be used to read data from input files .

 grammar :
while [[ condition ]]
do
If condition yes true , The orders here will be executed
done
#!/bin/bash
x=0
y=10
while [ ${x} -lt 5 ]
do
echo $x
x=`expr ${x} + 1`
done
# do It's also written in a line with the conditions , You need a semicolon in front of it ;
while [ ${y} -gt 5 ]; do echo $y; y=`expr ${y} - 1`; done

until loop

until The loop is to detect a condition , As long as the condition is false It's going to run the loop all the time , Until the condition is true Stop when . It goes with while Just the opposite .

#!/bin/bash
x=0
until [ ${x} -eq 5 ]; do
echo ${x}
x=`expr ${x} + 1`
done

select loop

select The syntax of loops follows for The cycle is basically the same . It helps us organize a user menu .

 grammar :
select Variable in list
do
Execute the corresponding command
done

select Will print the values of the list and their serial numbers to the screen , The user will then be prompted to choose , What users usually see is \$?, The user inputs the corresponding signal , The result of the selection will be saved to the variable .

#!/bin/bash
#PS3——shell Use in script select When the prompt
PS3=" Select the package management tool you want to install , Enter the serial number :"
select ITEM in bower npm gem pip
do
echo " The package name entered is :\c" && read PACKAGE
case ${ITEM} in
bower) echo " simulation bower install ${PACKAGE}" ;;
npm) echo " simulation npm install ${PACKAGE}" ;;
gem) echo " simulation gem install ${PACKAGE}" ;;
pip) echo " simulation pip install ${PACKAGE}" ;;
*) echo " Wrong selection of package management tool " ;;
esac
break # Out of the loop
done

break command

break The command allows you to jump out of all loops ( Terminate all loops after execution ). In a nested loop break The command can also be followed by an integer , Jump out of a loop .

#!/bin/bash
# When x be equal to 2, also y be equal to 0, Just jump out of the loop
for x in 1 2 3
do
for y in 0 5
do
if [ ${x} -eq 2 -a ${y} -eq 0 ]
then
echo "x be equal to ${x},y be equal to ${y}"
break 2
else
echo "${x} ${y}"
fi
done
done

continue command

continue Command to break Command similar , There's only one difference , It doesn't jump out of all loops , Just jump out of the current loop . Again ,continue It can also be followed by a number , How many layers of loop to jump out of .

#!/bin/bash
# When x be equal to 2, also y be equal to 0, Just jump out of the loop
for x in 1 2 3
do
for y in 0 5
do
if [ ${x} -eq 2 -a ${y} -eq 0 ]
then
continue 2
else
echo "${x} ${y}"
fi
done
done

function

  • shell Functions must be defined before they are used , Call a function using only its function name .
  • When a function is defined ,function Keywords are optional
  • Function return value : You can use it explicitly return sentence , Return value type can only be integer (0-255). If not return sentence , Will default to the last command run results as the return value .
  • Function return value after calling the function , adopt $? get .
 grammar : Brackets indicate optional
[function] function_name () {
Execute the command here
[return value]
}
#!/bin/bash
hello () {
echo "hello"
world # Nested function
}
world () {
echo "world"
}
hello

Parameters

Positional parameters are variables created when a function is called and passed its parameters , See above Shell Special variables .

#!/bin/bash
funWithParam () {
echo " The first 1 Parameters :$1"
echo " The first 2 Parameters :$2"
echo " The first 3 Parameters :$3"
echo " Wrong access to the first 10 Parameters :$10"
# $10 Can't get No 10 Parameters , Need to use ${10}, When n>=10 when , Need to use ${n} To obtain parameters .( There's compatibility , some Shell The interpreter can get both )
echo " Get it right 10 Parameters :${10}"
echo " For the first 11 Parameters :${11}"
echo " Get the number of transmitted parameters :$#"
echo " Get all the parameters :$*"
echo " The name of the current function is :$FUNCNAME"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73

I / O redirection

Unix Commands default from the standard input device (stdin) Get input , Output the results to the standard output device (stdout) Show . In general , The standard input device is the keyboard , The standard output device is the display .

I / O stream

shell Receives input , And produce output in the form of character sequence or character stream . These streams can be redirected to a file or to another stream .

In general , Every Unix/Linux The command will open three files : Standard input file 、 Standard output file 、 Standard error file , Three file descriptors :

Code The descriptor describe
0 stdin The standard input
1 stdout standard output
2 stderr Standard error output

Redirect

Redirection allows us to control where input to a command comes from , Where to output the results .

Output redirection : The output of a command can be more than just a display , You can also easily escape to files , This is called output redirection .

 grammar :
command > file This syntax will override the contents of the file
command >> file If you don't want the file to be covered , have access to >> Append to end of file 

Input redirection : send Unix Command can also get input from file , In this way, the command to get input from the keyboard will be transferred to the file to read the content .

 grammar :
command < file

There is a document that test.sh, Output the number of lines in the file in two ways

wc -l ./test.sh
# Output :14 ./test.sh
wc -l < ./test.sh
# Output :14 No file name 

The first example will output the file name , The second one won't , Because it only knows what to read from standard input .

The following operators are used to control the redirection of flow :

The operator describe
> Redirect output
>> Redirect the output to the appended way
>& Merge two output files
<& Merge two input files
< Redirect input
<< Here Document Syntax ( See extension below ), Will start marking tag And closing marks tag Between the content as input
<<< Here character string

If you want to stderr Redirect to file, It can be written like this :

command 2 > file

If you want to stdout and stderr Redirected after merge file, It can be written like this :

#&[n] Represents an existing file descriptor ,&1 For output &2 Stands for error output &- Represents closing the descriptor bound to it
command > file 2 >&1

If you want to stdin and stdout All redirects , It can be written like this :

command < file1 > file2
# for example :
cat < test.sh > catfile
# Mention it << This is two small symbols in succession , He stands for 『 Ending input character 』 It means . So when the blank line is entered eof character , Input automatically ends , no need ctrl+D
cat <<eof >catfile

If you want to execute a command , But I don't want to display the output on the screen , So you can redirect the output to /dev/null.

/dev/null It's a special document , Everything written to it will be discarded , If you try to read from the file , So you can't read anything . however /dev/null Documents are very useful , Redirect the output of the command to it , It's going to work " No output " The effect of .

#test1.sh Without it , Turn off the error output
ls test.sh test1.sh 2>/dev/null
ls test.sh test1.sh 2>&-
# Turn off all outputs
ls test.sh test1.sh 1>&- 2>&-
ls test.sh test1.sh 2>/dev/null 1>/dev/null
# Output the error 2 Bind to Output correctly 1, And then Output correctly Send to /dev/null equipment This is commonly used
ls test.sh test1.sh >/dev/null 2>&1
#& For standard output , Error output All standard output and error output Input to /dev/null file
ls test.sh test1.sh &>/dev/null

Loading external scripts

Like any other language ,Shell You can also load external scripts , Merge the contents of the external script into the current script .shell There are two ways to write external scripts loaded in .

 The first one is :. filename
The second kind :source filename

The two methods have the same effect , Simplicity , Generally, point numbers are used (.), however ! Note the number (.) And a space between the file name and

#!/bin/bash
. ./pre_test.sh
echo $a
# Output :100

Debug

overall situation Debug

shell Provided for debug Tools for scripting . If you want to use debug Mode to run a script , Can be in its shebang Use a special option in the .( There are some shell I won't support it )

#!/bin/bash [options]

Or in execution Bash Script time , Pass in these parameters from the command line

bash -euxo pipefail test.sh

Local Debug

Sometimes we just need to debug Part of the script . In this case , Use set The command will be convenient . This command can enable or disable options . Use - Enable options , Use + Disable options .

1、 Used before running the results , First output the line of command executed

set -x
# perhaps
set -o xtrace

2、 When executing a script , If you encounter a nonexistent variable, you will report an error , And stop executing .( The default is to ignore the error )

set -u
# perhaps
set -o nounset

By the way , If the command line does not take any parameters , Direct operation set, All environment variables and Shell function .

3、 When executing a script , Terminate execution on error .( The default is to continue execution )

set -e
# perhaps
set -o errexit
# You can use the following method
command || exit 1
# perhaps
command1 && command2

set -e Judge according to the return value , Whether a command fails to run . however , The non-zero return value of some commands may not indicate a failure , Or the developer wants to have a command fail , The script goes on . It can be closed temporarily set -e, After the execution of the command , Open it again set -e.

set +e
command1
command2
set -e
# You can also use the following method
command || true

4、 Pipeline command execution failed , The script terminates execution

A pipeline command is a number of subcommands through the pipeline operator (|) Combine it into one big command .Bash The return value of the last subcommand will be returned , As the return value of the entire command . The last subcommand does not fail , Pipeline commands always succeed , therefore set -e It will fail , Later orders will continue to be executed .

set -o pipefail To solve this situation , As long as one subcommand fails , The entire pipeline command will fail , The script will terminate execution .

set -eo pipefail

The commands above can be used together :

set -euxo pipefail
# perhaps
set -eux
set -o pipefail

Expand

The script interpreter specifies... In the environment variable

In addition to the more common way of specifying script interpreter with path , Another is to specify the script interpreter in the environment variable .

 Specify the path to the script interpreter
#!/bin/bash`
Specifies the script interpreter in the environment variable
#!/usr/bin/env bash

The advantage of this is , The system will automatically PATH Find the specified program in the environment variable ( As in the example bash). Because the path of the program is uncertain , For example, after installing the new version of bash after , We may add this new path to PATH in , Come on “ hide ” The old version of bash. So the operating system PATH Variables may be configured to point to another version of the program , If you still use it directly #!/bin/bash, Then the system will still choose the old version bash To execute the script , If you use #!/usr/bin/env bash, Will use the new version .

environment variable

All procedures , Include Shell The variables that can be accessed by the startup program at runtime are environment variables . stay shell Use in script export You can define environment variables , But only in the current running shell Effective in the process , The end of the process is gone . If you want to persist , Environment variables need to be defined in some column configuration files .

The loading order of the configuration file and shell Whether the process is running in Interactive and Login Patterns are about .

Interactive and non interactive patterns (Interactive & Non-Interactive)

  • Interactive Pattern : Usually refers to reading and writing data from the user's command line terminal (terminal), The user enters the command , And executed immediately after the return shell.
  • Non-Interactive Pattern : Usually refers to the execution of a shell Script , or bash -c Carry out orders

Detect current shell Is the running environment Interactive Pattern

[[ $- == *i* ]] && echo "Interactive" || echo "Non-interactive"

Login and non login mode (Login & Non-Login)

  • Login Pattern : When the terminal logs in ,ssh When the connection ,su --login <username> When switching users , It refers to the user who has successfully logged in Shell process , This will read /etc/passwd The user belongs to shell perform .
  • Non-Login Pattern : Applications run directly bash when ,su <username> When switching users ( I didn't add --login). It refers to the state of non login user shell process .

Detect current shell Is the running environment Login Pattern

shopt -q login_shell && echo "Login shell" || echo "Not login shell"
# If it is zsh, No, shopt command
[[ -o login ]] && echo "Login shell" || echo "Not login shell"

Get into bash It can also be used in interactive mode --login Parameter to determine whether it is login mode :

$> bash
$> shopt -q login_shell && echo "Login shell" || echo "Not login shell"
Not login shell
$> exit
$> bash --login
$> shopt -q login_shell && echo "Login shell" || echo "Not login shell"
Login shell
$> exit

Login In mode mode, you can use logout and exit sign out ,Non-Login In mode, you can only use exit sign out .

The configuration file ( Startup file ) Loading order

bash Supported profiles are /etc/profile、~/.bash.rc etc. .

As shown in the loading sequence above

  • Interactive&Login Pattern :/etc/profile —>( ~/.bash_profile, ~/.bash_login, ~/.profile) One of them —>~/.bash_loginout( sign out shell Called when the )
  • Interactive&Non-Login Pattern :/etc/bash.bashrc —>~/.bashrc
  • Non-Interactive Pattern : It's usually the execution of a script (script) When , In this case, the configuration items are read and executed from the environment variables , That is to say env perhaps printenv Configuration item for command output .

Today's systems generally don't have ~/.bash_profile The file , Only keep ~/.bashrc file , In all the systems ,~/.bash_profile There will be such logic , Avoid landing ~/.bashrc The situation of being skipped :

# login shell will execute this
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi

In the release version of Linux In the system ,Interactive&Login Mode of ~/.bash_profile, ~/.bash_login, ~/.profile It doesn't have to be one of three , If you look at the contents of these three scripts, you will find that they will continue to call the next configuration file it wants to call , In this way, the configuration items may need to be configured multiple times in different configuration files . Such as centos7.2 in ~/.bash_profile The file actually calls ~/.bashrc file .

# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/.local/bin:$HOME/bin
export PATH

As shown in the figure above , To start a Shell Process time , The values of some parameters also affect the loading of configuration files . Such as --rcfile,--norc etc. .

frequently-used shell environment variable :

Variable name describe
PATH Command search path , Use colon as separator
HOME The pathname of the user's home directory , yes cd The default parameters of the command
SHELL Currently running Shell Full pathname of
TERM Terminal type
LOGNAME Current login name
PWD Current working directory
# Two ways to output individual environment variable values
printenv HOME
echo $HOME

Global variables are variables that all users need to use , You can place new or modified variable settings in /etc/profile In file , But if you upgrade the distribution, the file will also be updated , So pay attention to this ( For all users ).

It's better to be in /etc/profile.d Create a directory to .sh Final document , Put all new or modified variables in this file ( For all users ).

For storage, individual users are permanent bash shell Where the variables are $HOME/.bashrc file . This applies to all types of shell process ( Only for current users ).

$* and $@ The difference between

$* and $@ Represents all parameters passed to a function or script , Not double quoted ("") Inclusion time , It's all about "$1" "$2" ... "\\$n" The form outputs all the parameters one by one .

But when they are enclosed in double quotation marks ,"$*" All parameters will be taken as a whole , With "$1 $2 ... $n" Output all parameters in the form of ."$@" It's the same as before , Separate all the parameters , One by one output .

for example :./test.sh a b c d


#/bin/bash
echo " Print out... Without quotation marks $*"
for var in $*
do
echo "$var"
done
# Output : Print out... Without quotation marks $*
# a
# b
# c
# d
echo " Print out quotation marks \"$*\""
for var in "$*"
do
echo "$var"
done
# Output : Print out quotation marks "$*"
# a b c d
echo " Print out... Without quotation marks $@"
for var in $@
do
echo "$var"
done
# Output : Print out... Without quotation marks $@
# a
# b
# c
# d
echo " Print out quotation marks \"$@\""
for var in "$@"
do
echo "$var"
done
# Output : Print out quotation marks "$@"
# a
# b
# c
# d

Shell Replace in

Escape character replacement

Use echo On command , Use -e You can replace the escape character . Use -E You can prohibit the escape of , Default is not escaped ; Use -n Option to disable the insertion of line breaks .

Escape character meaning
\b Backspace ( Delete key )
\f Change the page (FF), Move the current position to the beginning of the next page
\n Line break
\c Show no line breaks
\r enter
\t Horizontal tabs (tab key )
\v Vertical tabs

#/bin/bash
a=1
b=2
echo -e "${a}\n${b}" # Output :1
# 2

Command substitution

Command substitution means Shell You can execute the order first , Save the output temporarily , Output... In the right place .

The syntax of command substitution is : The quotation marks ``.


#!/bin/bash
DATE=`date`
echo " The date is :\$DATE" # Output : The date is :Sun Oct 18 16:27:42 CST 2020

() and (())

But first, let me say ()

stay bash in ,\$() And ``( The quotation marks ) They're used for command substitution . Complete the command line in quotes , Then replace the result with , And the new command line .

The same thing :\$() And `` In operation , Both of these are to achieve the corresponding effect

Difference :`` It's easy with '' Chaos , Especially for beginners , and \$( ) intuitive ; however \$() Compatibility issues , Some classes Unix The system does not support .

echo $(expr 1 + 2)

Besides, (())

1、(()) It can be directly used in integer calculation

echo $((1 + 2))

2、(()) Variable values can be redefined , Used to judge conditions or calculations, etc

#!/bin/bash
a=10
b=50
((a++))
echo $a
# Output :11
((a > b)) && echo "a > b"
((a < b)) && echo "a < b"
# Output :a < b

3、(()) It can be used for base conversion

\$(()) You can convert other base numbers to decimal numbers and display them . grammar :$((N#xx)), among ,N In base ,xx Is a numeric value under the base , After the command is executed, you can get the decimal value of the decimal number .

echo $((2#110))
# Output :6
echo $((8#11))
# Output :9
echo $((16#1a))
# Output :26

test 、[] and [[]]

type Command check

type "test" "[" "[["
# Output :
#test is a shell builtin
#[ is a shell builtin
#[[ is a reserved word

As can be seen from the above ,test and [ Belong to Shell Built-in commands ,[[ Belong to Shell Reserved keywords for .

On the use ,test and [ It is equivalent. , Because it's an order , So you need to separate it from its parameters with spaces .

test -f /etc/hosts && echo True
# Output :True
[ -f /etc/hosts ] && echo True
# Output :True

because ] As the last parameter, it indicates the end of the condition , And like <> The symbol will be understood as redirection , Cause error

[ 1 < 2 ]
# Output :line 13: 2: No such file or directory

[[ Is the key word , Be able to understand the content according to the conventional semantics , The expression in double brackets is treated as a single statement , And return its status code .

[[ 1 < 2 ]] && echo True || echo False
# Output :True

Recommended [[ To make all kinds of judgments , Many mistakes can be avoided .

The following shows the errors caused by single brackets

[ $a == 1 && $b == 1 ] && echo True || echo False
# Output :[: missing `]'
# for example $a It's empty , Will report grammatical errors , because [ What the order actually got was ==、1、] Three parameters
[ $a == 1 ]
# Output :[: ==: unary operator expected

Here Document

Here Document It can be understood as “ The embedded document ”.Here Document yes Shell A special way of redirection , Its basic form is as follows :


command <<delimiter
document
delimiter

The function is to combine two delimiter Content between (document) Pass as input to command.

Be careful :

  • At the end of the delimiter Be sure to write at the top , There can't be any characters in front of it , There can't be any characters after it , Including spaces and tab Indent .
  • At the beginning delimiter Before and after the space will be ignored .
#!/bin/bash
wc -l << EOF
line 1
line 2
line 3
EOF # Output :3

Reference documents

版权声明
本文为[Fang Xu]所创,转载请带上原文链接,感谢

  1. [front end -- JavaScript] knowledge point (IV) -- memory leakage in the project (I)
  2. This mechanism in JS
  3. Vue 3.0 source code learning 1 --- rendering process of components
  4. Learning the realization of canvas and simple drawing
  5. gin里获取http请求过来的参数
  6. vue3的新特性
  7. Get the parameters from HTTP request in gin
  8. New features of vue3
  9. vue-cli 引入腾讯地图(最新 api,rocketmq原理面试
  10. Vue 学习笔记(3,免费Java高级工程师学习资源
  11. Vue 学习笔记(2,Java编程视频教程
  12. Vue cli introduces Tencent maps (the latest API, rocketmq)
  13. Vue learning notes (3, free Java senior engineer learning resources)
  14. Vue learning notes (2, Java programming video tutorial)
  15. 【Vue】—props属性
  16. 【Vue】—创建组件
  17. [Vue] - props attribute
  18. [Vue] - create component
  19. 浅谈vue响应式原理及发布订阅模式和观察者模式
  20. On Vue responsive principle, publish subscribe mode and observer mode
  21. 浅谈vue响应式原理及发布订阅模式和观察者模式
  22. On Vue responsive principle, publish subscribe mode and observer mode
  23. Xiaobai can understand it. It only takes 4 steps to solve the problem of Vue keep alive cache component
  24. Publish, subscribe and observer of design patterns
  25. Summary of common content added in ES6 + (II)
  26. No.8 Vue element admin learning (III) vuex learning and login method analysis
  27. Write a mini webpack project construction tool
  28. Shopping cart (front-end static page preparation)
  29. Introduction to the fluent platform
  30. Webpack5 cache
  31. The difference between drop-down box select option and datalist
  32. CSS review (III)
  33. Node.js学习笔记【七】
  34. Node.js learning notes [VII]
  35. Vue Router根据后台数据加载不同的组件(思考-&gt;实现-&gt;不止于实现)
  36. Vue router loads different components according to background data (thinking - & gt; Implementation - & gt; (more than implementation)
  37. 【JQuery框架,Java编程教程视频下载
  38. [jQuery framework, Java programming tutorial video download
  39. Vue Router根据后台数据加载不同的组件(思考-&gt;实现-&gt;不止于实现)
  40. Vue router loads different components according to background data (thinking - & gt; Implementation - & gt; (more than implementation)
  41. 【Vue,阿里P8大佬亲自教你
  42. 【Vue基础知识总结 5,字节跳动算法工程师面试经验
  43. [Vue, Ali P8 teaches you personally
  44. [Vue basic knowledge summary 5. Interview experience of byte beating Algorithm Engineer
  45. 【问题记录】- 谷歌浏览器 Html生成PDF
  46. [problem record] - PDF generated by Google browser HTML
  47. 【问题记录】- 谷歌浏览器 Html生成PDF
  48. [problem record] - PDF generated by Google browser HTML
  49. 【JavaScript】查漏补缺 —数组中reduce()方法
  50. [JavaScript] leak checking and defect filling - reduce() method in array
  51. 【重识 HTML (3),350道Java面试真题分享
  52. 【重识 HTML (2),Java并发编程必会的多线程你竟然还不会
  53. 【重识 HTML (1),二本Java小菜鸟4面字节跳动被秒成渣渣
  54. [re recognize HTML (3) and share 350 real Java interview questions
  55. [re recognize HTML (2). Multithreading is a must for Java Concurrent Programming. How dare you not
  56. [re recognize HTML (1), two Java rookies' 4-sided bytes beat and become slag in seconds
  57. 【重识 HTML ,nginx面试题阿里
  58. 【重识 HTML (4),ELK原来这么简单
  59. [re recognize HTML, nginx interview questions]
  60. [re recognize HTML (4). Elk is so simple