Detailed explanation of shell script writing syntax

1 Basic grammar

1.1 Variables

Variables: Use a string of fixed characters to represent a variable target.

1.1.1 Variable types

There will be three types of variables in the shell at the same time.

  • Local variables: Local variables are defined in scripts or commands, and are only valid in the current shell instance. Programs started by other shells cannot access local variables.

  • Environment variables: All programs, including programs started by the shell, can access environment variables, and some programs need environment variables to ensure their normal operation.

    Shell scripts can also define environment variables when necessary.

  • Shell variables: Shell variables are special variables set by shell programs.

    Some of the shell variables are environment variables and some are local variables, which ensure the normal operation of the shell

1.1.2 Variable operation

  1. Create ordinary variables: name = "test",Note: There can be no spaces on both sides of the equal sign
  2. Create a local variable: local name = "test",Modified localvariables cannot be accessed outside the function body and can only be used in the function body
  3. Create a read-only variable: name="only_read" -> readonly name,This variable cannot be modified
  4. Use variables: echo $name or echo ${name}
  5. Delete variable: unset name, the variable after deletion cannot be accessed,Note: read-only variables cannot be deleted

1.1.3 String variables

1.1.3.1 Creation of String Variables

  1. Created with single quotes: var='test'

    The variable created in this way can only be output as it is, and the variable is invalid. We can borrow the definition of "string constant" in c to understand this feature.

    In addition, single quotation marks cannot appear in single quotation marks, and escaping is also not allowed.

  2. Created with double quotes: var="my name is ${name}"

    String variables created in this way are valid, and escape characters can also appear.

1.1.3.2 Concatenating Strings

  1. Literal splicing
    str="1""2" or str01="1"'2', so that the two characters 1 and 2 are spliced ​​together. It should be noted that there can be no spaces between the two strings.

  2. Variable splicing: The following three methods can splice string variables.

    • str=${part01}${part02}
    • str02=${part01}“end”
    • str03=“${part01} ${part02}”
  3. Command splicing: date here is a shell command, which needs to be quoted
    str= date "end"

    str02=`date`"end"
    

1.1.3.3 Get the string length

  1. use wc -Lcommand

wc -LThe length of the current line can be obtained, so this simple method can be used to obtain the string of a single line, and the wc -lnumber of lines of the current string content is obtained.

echo "abc" |wc -L
  1. expr lengthThe length of the string can be obtained using
expr length ${<!--{C}%3C!%2D%2D%20%2D%2D%3E-->str}
  1. Awk gets the number of domains

But if there is a problem when the length is greater than 10 characters, it needs to be confirmed later

echo "abc" |awk -F "" '{print NF}'
  1. awk+lengthGet the string length by
echo "Alex"|awk '{print length($0)}'
  1. echo ${#name}way of passing
echo "Alex"|awk '{print length($0)}'

1.1.3.4 Extract substring

the code significance
${varible##*string} Intercept the string after the last string from left to right
${varible#*string} Intercept the string after the first string from left to right
${varible%%string*} Intercept the string after the last string from right to left
${varible%string*} Intercept the string after the first string from right to left
$ var=firenation.jpg
$ echo ${var##*i}

The result of the operation ison.jpg

2. use${varible:n1:n2}

Intercept the string of variable varible from n1 to n2, and select a specific substring according to a specific character offset and length, as shown in the following code:

$ var=azula
$ echo ${var:0:3}

The running results are finally displayed azu.

1.1.4 Arrays

An array is a collection of variables that store multiple elements in a contiguous memory space.

In bash, only one-dimensional arrays are supported, multidimensional arrays are not supported.

1.1.4.1 Array definition and reference

An array is defined as follows:

数组名=(元素1 元素2 元素1 ... 元素n)

Assign values ​​to the elements of the specified array corresponding to the subscript:

数组名[下标]=

Specify multiple array elements for assignment at the same time:

数组名=([下标1]=值1 [下标2]=值2 ... [下标n]=值n)

To reference an element of an array corresponding to a subscript:

${数组名[下标]}

1.1.4.2 Traversing array elements

Use for(or whileloop) to loop through array elements:

#!/bin/bash
a=(1 2 3 4 5 6)
for((i=0; i<10; i++))
do
    echo "a[$i]=${a[$i]}"
done

In addition, we can also use ${a[*]}or ${a[@]}to traverse array elements, the specific code is as follows:

#!/bin/bash
a=(1 2 3 4 5 6)
echo ${a[*]}
echo ${a[@]}

1.1.4.3 Get the length of the array

We can use #to get the length of the array. It should be noted that in the shell script, when we access the array out of bounds, no error will be reported.

#!/bin/bash
a=(1 2 3 4 5 6)
echo ${a[*]}
echo "a len: ${
     
     #a[*]}"

We first use it to get the elements in the array and then use it #to get the number of elements.

1.1.4.4 Merging Arrays

We can splice as follows:

#!/bin/bash
a=(1 2 3 4 5 6)
b=("hello" "zhaixue.cc")
c=(${a[*]} ${b[*]})

This way we concatenate the two arrays together.

1.1.4.5 Delete array elements

If we want to delete an array element, the specific code is as follows:

#!/bin/bash
a=(1 2 3 4 5 6)
echo ${a[*]}
echo "a len: ${
     
     #a[*]}"
unset a[5]
echo ${a[*]}
echo "a len: ${
     
     #a[*]}"

If we want to delete the entire array, we can execute it unset a. The example code is as follows:

#!/bin/bash
a=(1 2 3 4 5 6)
echo ${a[*]}
echo "a len: ${
     
     #a[*]}"
unset a
echo ${a[*]}
echo "a len: ${
     
     #a[*]}"

1.1.3 Variable parameter passing

The relevant variable meanings are:

variable meaning
$0 The name of the file to execute
$1 Represents the first parameter passed in
$n Represents the nth parameter passed in
$# Number of parameters
$* Displays all arguments passed to the script as a single string .
$@ Same as $*, but use quotes and return each argument in quotes
$$ The current process number where the script is running
$! The ID of the last process running in the background
$? Display the exit status of the last command. 0 means no errors, any other value indicates errors.

1.2 Operators

Native bash does not support simple mathematical operations, usually through other commands to achieve.

1.2.1 Arithmetic operators

aThe sums and sums in the following tables bare variables.

operation format in shell
addition expr $a + $b
subtraction expr $a - $b
multiplication expr $a \* $b
division expr $b / $a
Take the remainder expr $b % $a
assignment a=$b
equal [ $a == $b ]
not equal [ $a != $b ]

Note: The condition table formula needs to be placed between square brackets, and there must be spaces. use

expr

Backticks need to be used for calculations. In order to make it easier for readers to understand, the following sample code is given.

#!/bin/bash
a=10
b=20

val=`expr $a + $b`
echo "a + b : $val"

1.2.2 Relational operators

Relational operators only support numbers, not strings, unless the value of the string is a number.

operation Implementation in the shell main symbol
Checks if two numbers are equal [ $a -eq $b ] -eq
Checks if two numbers are not equal [ $a -ne $b ] - is
Check if the number on the left is greater than the number on the right [ $a -gt $b ] -gt
Check if the number on the left is less than the number on the right [ $a -lt $b ] -lt
Check if the number on the left is greater than or equal to the number on the right [ $a -ge $b ] -ge
Check if the number on the left is less than or equal to the number on the right [ $a -and $b - the

The example code is as follows:

#!/bin/bash
a=1
b=2

if [ $a != $b ]
then
   echo "$a != $b : a 不等于 b"
else
   echo "$a == $b: a 等于 b"

1.2.1 Boolean operators

details as follows:

operation Implementation in the shell main symbol
not operation [ ! false ] !
OR operation [ $a -lt 20 -o $b -gt 100 ] -o
AND operation [ $a -lt 20 -a $b -gt 100 ] -a

1.2.2 Logical operators

details as follows:

operation Implementation in the shell main symbol
Logical AND [[ $a -lt 100 && $b -gt 100 ]] &&
Logical OR [[ $a -lt 100 `

The difference between boolean operators and logical operators:

Syntactically, logical operations require double brackets, and Boolean operations only require single curly brackets Functionally, logical operations have a special short-circuit function, that is, when the first expression is false in the AND operation, the second expression will not be executed. In an OR operation, the second expression is not executed if the first expression is true.

1.2.3 String operators

The following table lists commonly used string operators:

operation Implementation in the shell main symbol
Checks if two strings are equal [ $a = $b ] =
Checks if two strings are not equal [ $a != $b ] !=
Check if the string length is 0 [ -z $a ] -z
Check if the string length is not 0 [ -n “$a” ] -n
Check if the string is empty [ $a ] $

1.2.6 File Test Operators

Mainly used to detect various attributes of unix files:

operation Implementation in the shell main symbol
Check if a file is a block device file [ -b $file ] -b file
Check if a file is a character device file [ -c $file ] -c file
Check if a file is a directory [ -d $file ] -d file
Check if a file is an ordinary file (neither a directory nor a device file) [ -f $file ] returns true -f file
Check if a file has the SGID bit set [ -g $file ] -g file
Check if a file has a sticky bit set (Sticky Bit) [ -k $file ] -k file
Check if a file is a named pipe [ -p $file ] -p file
检测文件是否设置了 SUID 位 [ -u $file ] -u file
检测文件是否可读 [ -r $file ] -r file
检测文件是否可写 [ -w $file ] -w file
检测文件是否可执行 [ -x $file ] -x file
检测文件是否为空(文件大小是否大于0) [ -s $file ] -s file
检测文件(包括目录)是否存在 [ -e $file ] -e file

举例如下:

#!/bin/bash
file="/home/westos/Desktop/textcpp/test.sh"
if [ -r $file ]
then
   echo "文件可读"
else
   echo "文件不可读"
fi

1.2.7 运算指令

1.(( ))

我们可以直接使用双圆括弧计算其中的内容,如((var=a+b))

该指令经常在if/while等条件判断中需要计算时使用。

2.let

在计算表达式的时候我们可以直接使用let

如:let var=a+b。

3.expr

在前面的内容中我们也提到了它,是非常常用的计算指令,使用时需要在外部增反引号

 var=`expr a+b`

4.bc计算器

bc计算器支持shell中的小数进行运算,并且可以交互式或者非交互式的使用。

基本使用方式为var=$(echo "(1.1+2.1)"|bc)

5.$[]

我们可以直接使用这种方式计算中括弧中的内容,如echo $[1+2]

1.3 控制语句

和其他语句不同,shell的流传呢个控制不可为空。接下来我们为大家介绍sehll中常用的语法。

1.3.1 if语句结构

1.3.1.1 if-fi

就类似于c中的if条件判断,如下:

if condition
then
    command1 
    command2
    ...
    commandN 
fi

1.3.1.2 if-else-fi

代码如下:

if condition
then
    command1 
else
    command2
fi

若condition成立则执行command1,否则执行command2。

1.3.1.3 if else-if else

代码如下:

if condition1
then
    command1
elif condition2 
then 
    command2
else
    command3
fi

1.3.2 循环结构

1.3.2.1 for循环

格式为:

for var in item1 item2 ... itemN
do
    command1
    command2
    ...
    commandN
done

以上也可以写做一行,若变量var在列表中,则for循环执行一次所有命令。以以下代码作为测试:

#!/bin/bash
for loop in 1 2 3 4 5
do
    echo "The value is: $loop"
done

1.3.2.2 while循环

格式如下:

while condition
do
    command
done

我们运行如下代码:

#!/bin/bash
int=1
while(( $int<=5 ))
do
    echo $int
    let "int++"
done

1.3.2.3 无限循环

我们可以以上两种语句给出无限循环的实现,首先看一下for循环如何实现:

for (( ; ; ))

除此以外我们也可以使用while循环实现如下:

while :
do
    command
done

或者直接将while中的判断语句置为真:

while true
do
    command
done

1.3.2.4 until循环

until 循环执行一系列命令直至条件为 true 时停止。语法格式如下:

until condition
do
    command
done

1.3.2.5 跳出循环

在循环过程中,有时候需要在未达到循环结束条件时强制跳出循环,Shell使用两个命令来实现该功能:breakcontinue

1.break跳出循环

当我们需要跳出当前循环,或者终止死循环时,我们就可以使用break来跳出循环。接下来我们运行如下代码:

#!/bin/bash
var=1
while(( $var < 5 ))
do
        if(( $var>3 ))
        then
             echo "跳出循环"
             break
        fi
        echo "$var"
        var=`expr $var + 1`
done

在该循环中var>1时break,而是直接跳出循环。

2.continue跳出循环

continue命令与break命令类似,只有一点差别,它不会跳出所有循环,仅仅跳出当前循环。 接下来我们运行如下代码:

#!/bin/bash
var=1
while(( $var < 5 ))
do
        if(( $var>3 ))
        then
             echo "跳出循环"
             continue
        fi
        echo "$var"
        var=`expr $var + 1`
done

使用continue跳出的循环只是当前循环,无法跳出整个循环,由于在该代码中我们每次执行到continue就会跳出当前循环,无法执行 var=expr $var + 1,所以循环条件一直成立,就成了死循环。

1.3.3 case-esac多选择语句

  • case ... esac 为多选择语句。
  • 与其他语言中的switch ... case 语句类似,是一种多分支选择结构
    • 每个 case 分支用右圆括号开始
    • 用两个分号 ;;表示 break,跳出整个 case … esac 语句
    • esac(就是 case 反过来)作为结束标记。
  • case 要求取值后面必须为单词 in,每一模式必须以右括号结束。取值可以为变量或常数,匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;。
  • 若检测匹配时无一匹配,使用*捕获该值,再执行后续命令。

语法格式如下:

casein
模式1)
    command1
    command2
    ...
    commandN
    ;;
模式2)
    command1
    command2
    ...
    commandN
    ;;
   *)
    command1
esac

1.3.4 select-in语句

select ... in ...非常适合终端的交互场景,它可以显示出带编号的菜单,用户出入不同编号就可以选择不同的菜单,并执行不同的功能。

语法格式如下:

select var in seq
do
    action
done

我们执行如下代码:

#!/bin/bash

echo "What is your favourite OS?"
select var in "Linux" "Mac" "Win" "Other"; do
  break;
done
echo "You have selected $var"

2 函数

函数其实就是将一段代码组合封装在一起实现某个特定的功能或返回某个特定的值。我们在定义函数时需要先起一个函数名,在使用的时候直接调用函数名即可

2.1 定义函数

shell中定义函数格式如下:

[ function ] funname [()]
{
    
    
    action;
    [return int;]
}

注意:

  1. [ function ]可以省略
  2. 当函数没有return时,默认返回最后一个命令的运行结果作为返回值(有点像Scala?)

2.2 函数参数

在shell中,调用函数时可以向其传递参数。在函数内部直接通过$n获取参数的值。我们给出示例如下:

#!/bin/bash
funWithParam(){
    
    
    echo "第一个参数为 $1 !"
    echo "第十个参数为 ${10} !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73

需要注意$10不能返回第十个参数,当n>10的时候,需要使用${n}来获取参数。

2.3 函数作用域

Shell脚本中执行函数时并不会开启子进程,默认在函数外部或函数内部定义和使用变量的效果相同。函数外部的变量在函数内部可以直接调用,反之函数内部的变量也可以在函数外部直接调用。

为了更好区分,系统为我们提供了local语句,该语句可以使在函数内部定义的变量仅在函数内部有效。定义时直接在变量前加local即可。

3 重定向

一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端。同样,一个命令通常将其输出写入到标准输出,默认情况下,这也是你的终端。

一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:

  1. 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
  2. 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
  3. 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。

但有些时候我们可能需要将数据从其它文件读入或读出,这就需要我们重定向。

3.1 输入重定向

我们可以让命令从文件中获取,这样本来的命令需要从标准输入stdin中获取,转换为从我们的指定文件中获取。这样本来需要从键盘输入的命令就会转移到文件读取内容。语法如下:

command1 < file

3.2 输出重定向

同输入重定向很相似,输出重定向也是将本来需要输出标准输出文件stdout中转化为我们的指定文件中。语法如下:

command1 > file

3.1 标准错误文件重定向

我们可以直接借助标准错误文件的文件描述符来重定向stderr,语法如下:

$ command 2>file

扩充一点,如果我们想将stdout标准输出文件和stderr标准错误文件合并重定向到一个指定文件中,语法如下:

$ command > file 2>&1

3.2 Here Document

Here Document 是 Shell 中的一种特殊的重定向方式,用来将输入重定向到一个交互式 Shell 脚本或程序。它的作用是将两个 delimiter 之间的内容(document) 作为输入传递给 command。基本语法如下:

command << delimiter   documentdelimiter

注意:结尾的delimiter 一定要顶格写,前面不能有任何字符,后面也不能有任何字符,包括空格和 tab 缩进。开始的delimiter前后的空格会被忽略掉。

3.3 /dev/null 文件

  • 如果希望执行某个命令,但又不希望在屏幕上显示输出结果,那么可以将输出重定向到 /dev/null中,/dev/null 是一个特殊的文件,写入到它的内容都会被丢弃;
  • 如果尝试从该文件读取内容,那么什么也读不到。但是 /dev/null 文件非常有用,将命令的输出重定向到它,会起到"禁止输出"的效果。语法如下:
$ command > /dev/null

Guess you like

Origin blog.csdn.net/twi_twi/article/details/128406613