[Linux][基础篇]--shell script

为什么要学习shell script

 脚本分多种类别,如shell、python、bat等,不同的场合下使用不同的脚本,python应用的范围最广,日常办公、大数据搜集、网络爬虫等都可以使用,bat是windows下的脚本文件。在本文中,只总结一些关于shell的语法,对于Linux工程师,我们都很熟悉shell,与Linux内核打交道需要shell,还有Android系统、Linux系统的编译都有shell的参与,因为shell脚本的存在,我们执行编译命令时不用手动敲击一堆命令,它可以解放我们的双手,自动化地帮助我们完成一些工作。

shell script规则

 shell script其实是一个纯文本文件,只是我们给予了它一些规则后变成了不需要编译就可以直接运行的程序,如下:

  • 命令的执行顺序:从上而下,自左向右。
  • 命令、参数间的多个空白都会被忽略掉。
  • 空白行也将被忽略掉,即使是[tab]按键所得的空白行也会被忽略掉。
  • 如果读取到一个Enter符号,就尝试开始执行该行命令。
  • 如果一行的内容太多,可以使用“[Enter]”来扩展到下一行。
  • "#"作为批注,后面的字符将被忽略,不会被执行。
  • shell script文件以 *.sh 为扩展名,并且必须赋予可执行权限。
  • 执行 test.sh 文件(以test.sh文件为例)最常用的方法是进入test.sh文件所在的目录下,敲击 ./test.sh 。
  • 有时也将test.sh文件放在PATH路径下,这样也可以通过 sh test.sh 来执行shell script。

hello world

 很自然,编写hello world是学习一种语言的第一步,对于shell script亦是如此,通过一个简单的 hello world 程序来学习编写shell script的基本规则。

#!/bin/bash 

# Program:
#       This program shows "Hello world" in your screen.
# History:
# 2021/08/3 Zhengqing.Yang First release

echo "Hello World!"

exit 0

 对以上shell script做一些解释:

  1. 第一行 #!/bin/bash声明这个script使用的shell名称
     当程序被执行时,它就能够加载bash的相关环境配置文件,一般是~/.bashrc,并且调用bash执行下面的命令。如果没有声明这一行,系统无法识别该文件,从而无法成功执行。

  2. 程序内容说明
     除了 “#!” 外,其余所有 “#” 后面的内容都是注释,在shell script中只有 “#” 能起到注释的作用,"//" 和 "/**/"都不行。
     每一条语句后面没有 “;” 分号结尾,在shell script中分号的作用是执行连续的命令。
     一些必要的程序声明,比如功能、版本号、作者等,这种好习惯对于以后程序的维护有很大的帮助。

  3. echo 命令是用于字符串的输出,exit 0表示脚本执行完成后回传一个0给系统,用户可以在命令行模式下敲击echo $?获取其返回值。其实, Linux下的命令执行结束后,也会返回一个值,一般情况下,命令执行成功返回0,失败返回非0 值,所以在写shell脚本时,我们也可以学它返回一个值。

循序渐进

交互式脚本

 我们也许会有这样的经历,在我们安装程序的时候,有时候系统会反问我们要安装到哪个目录去,是否确定安装之类的,这就是人机交互,在这种现像的背后,其实是脚本默默地在运行,它指挥着系统做一些我们希望完成的事情。那么在Linux下如何实现人机交互呢?交互,说的是输入和输出,站在脚本的角度来说,将数据从命令行读到变量中就叫输入,将变量的值输出到命令行叫输出,在shell脚本语法中仅仅通过两个命令就可以实现输入输出。

#!/bin/bash 

# Program:
#       This program shows "Hello world" in your screen.
# History:
# 2021/08/3 Zhengqing.Yang First release

read -p "Please input your first name: " firstname
read -p "Please input your last name: " lastname

echo "Your full name is:$firstname $lastname"

exit 0
  • read 是从命令行读取内容,将内容保存在变量firstname和lastname中,-p表示在执行读操作前打印提示信息。
  • $firstname,$lastname表示获取这两个变量的值,echo 命令将其打印到屏幕上,如图1所示。

图1

利用日期命名文件

 在数据库的维护中,或者在debug程序的时候,可能需要我们创建很多的log文件,创建文件对于我们来说不是难事,记住一两个文件也是小case,但是对于文件数目很多,时间有长久的情况下呢,这就难度大了,可能记不清各个文件是干什么用的,什么时候创建的,有时候真的会苦恼于这些文件的命名方式。对于在需要创建多个文件的情况下,我们可以使用“功能+日期”这种命名方式。

1 
  2 #!/bin/bash 
  3 
  4 # Program:
  5 #       Program creates three files,which named by user's input
  6 #       and date command.
  7 # History:
  8 # 2021/08/3 Zhengqing.Yang First release
  9 
 10 
 11 #打印提示信息
 12 echo "I will use 'touch' command to create 3 files."
 13 
 14 #从标准输入读取文件名
 15 read -p "Please input your filename: " fileuser
 16 
 17 #判断是否输入了文件名
 18 filename=${fileuser:-"filename"}
 19 
 20 #利用date命令获取时间
 21 date1=$(date --date='2 days ago' +%Y%m%d) #前两天的日期
 22 date2=$(date --date='1 days ago' +%Y%m%d) #前一天的日期
 23 date3=$(date +%Y%m%d) #今天的日期
 24 
 25 #整合文件名
 26 file1=${filename}${date1}
 27 file2=${filename}${date2}
 28 file3=${filename}${date3}
 29 
 30 #创建文件
 31 touch "$file1"
 32 touch "$file2"
 33 touch "$file3"
 34 
 35 exit 0

s h e l l 语 法 分 析 : \color{Crimson}{shell语法分析:} shell

  • file1=${filename}${date1}
    这条语句的模型是${变量},意思是分别获取变量filename和date1的值,并组合在一起赋值给变量file1。
  • date3=$(date +%Y%m%d)
    $()里面装的是命令,模型是$(变量),这条语句的意思首先执行date命令,然后通过$获取date命令的结果,最后赋值给变量date3。
  • filename=${fileuser:-“filename”}
    若变量fileuser为空时,取string filename为值,若不为空,则取变量fileuser为值。其变种还有三种,分别为:
     (1)filename=${fileuser:=“filename”}:规则和上面第一个一样。
     (2)filename=${fileuser:+“filename”}:规则跟上面的相反,当fileuser不为空时取string filename,fileuser为空时,取空值。
     (3)filename=${fileuser:?“filename”}:当fileuser不为空时,取fileuser的值,当fileuser为空时,string filename输出到标准错误中,并退出程序。
  • “string”
    双眼号里面的是字符串。
  • $((运算内容))
    美元符+双括号的功能是算数运算,比如+、-、*、/、%,shell支持整数计算。

判断文件是否存在

 判断文件存在与否,在Linux 命令行模式下可以使用find命令,也可以使用test命名,一般情况下,find命令会用的多一些,shell脚本中通常使用testtest命令的功能强大,不仅仅只用于文件,它还可以用于判断字符串是否为空,是否相等 ,以及变量的大小等,在这里我们学习shell脚本下test的使用方法,程序的逻辑如下:

  1. 让用户输入一个文件名,然后判断该文件是否存在,若不存在,则打印“File is not exit”,并中断程序;
  2. 若这个文件存在,则判断是文件还是目录,结果输出“File is regular file”或“File is directory”;
  3. 若该文件存在,输出程序执行者对该文件或目录的权限数据。

  2 #!/bin/bash 
  3 
  4 # Program:
  5 #       User input a filename,Program will check the flowing:
  6 #       1.)exit? 2.file/directory 3.)file permission
  7 # History:
  8 # 2021/08/05 Zhengqing.Yang First release
  9 
 10 #打印提示信息
 11 echo "Please input a filename,I will check the filename's type and permission"
 12 
 13 #用户输入文件名
 14 read -p "Input a filename: " filename
 15 
 16 #判断文件名是否为空
 17 test -z $filename && echo "You must input a filname." && exit 0
 18 
 19 #判断文件是否存在,若不存在则显示信息并退出程序
 20 test ! -e $filename && echo "The file '$filename' is not exit." && exit 0
 21 
 22 #判断文件类型与属性
 23 test -f $filename && filetype="regular file"
 24 test -d $filename && filetype="directory"
 25 test -r $filename && perm="readable"
 26 test -w $filename && perm="$perm writable"
 27 test -x $filename && perm="$perm executable"
 28 
 29 #输出最终结果信息
 30 echo "The file: $filename is a $filetype"
 31 echo "And the permission are: $perm"
 32 
 33 exit 0

s h e l l 语 法 分 析 : \color{Crimson}{shell语法分析:} shell
 在上面的程序中,主要语法是test命令,其他一些基本语法在前面已经了解过,关于test命令一些常用的选项在下表列出:

选项代表意义
test -z string判断字符串是否为空,若string位空,则为true
!反向状态,如test ! -x file,当file 不具有-x时,回传true
-e该文件是否存在
-f该文件是否存在且为文件
-d该目录是否存在且为目录
-r检测该文件是否存在且具有可读权限
-w检测该文件是否存在且具有可写权限
-x检测该文件是否存在且具有可执行权限
-o任何一个条件成立!类似 ||(或)
-a两个条件同时成立!类似&&(与)
-lttest n1 -lt n2,n1 小于等于 n2

中括号[]的用法

 在shell script中,具有判断功能的语法不仅仅只有test命令,还有中括号[],用法与test一模一样,只是需要注意以下几点:

  1. 在中括号[]内的每个组件都需要有空格键来分隔。
  2. 在中括号[]内的变量,最好都以双引号括号起来。
  3. 在中括号[]内的常量,最好都以单或双引号括号起来,否则会出现以下这样的错误。原因是翻译过来就是这样的,[ hello world == “hello” ],中括号[]判定式只能有两个参数,所以发生错误了。

图2

正确的写法应该是:[ “$name” == “hello” ]
4. test 和 [] 中,==和!=只能用于比较字符串,而且结果为真时,返回1,结果为假时,返回0。

 简单写个小程序:

1 
  2 #!/bin/bash 
  3 
  4 # Program:
  5 #       This program shows the user's choice.
  6 # History:
  7 # 2021/08/05 Zhengqing.Yang First release
  8 
  9 #从标准输入读取字符串
 10 read -p "Please input (Y/N): " yn
 11 
 12 #判断是否输入 y或Y
 13 [ "$yn" == "Y" -o "$yn" == "y" ] && echo "OK,continue" && exit 0
 14 
 15 #判断是否输入 n或N
 16 [ "$yn" == "N" -o "$yn" == "n" ] && echo "OK,interrupt" && exit 0
 17 
 18 #打印提示信息
 19 echo "I don't known what you choice is" && exit 0
 20 
 21 exit 0

s h e l l 语 法 分 析 : \color{Crimson}{shell语法分析:} shell
 用户输入y或n,忽略大小写,程序判断是否输入了y或n,若是,则返回1,继续执行&&后面的语句。在中括号[]中,-o是test命令的选项,表示任何一个条件成立都返回1。


图3
## 传递参数  执行shell script时,如何向shell script传递参数进去呢?类似这种``./sh06.sh para1 para2 para3 ...``。首先关于参数传递需要记得几个默认的变量,它们是: * $#:代表后接的参数个数 * $@:代表"$1","$2","$3"之意,每个变量都是独立的 * $*:代表"$1 $2 $3" * $0:代表文件名 * $1:代表第一个参数 * $2:代表第二个参数 * $3:代表第三个参数 * ...
 
  2 #!/bin/bash 
  3 
  4 # Program:
  5 #       This program shows script name,parameters.
  6 # History:
  7 # 2021/08/07 Zhengqing.Yang First release
  8 
  9 #输出脚本的文件名
 10 echo "The script name is ==> $0"
 11 #输出参数的个数
 12 echo "Total parameter number is ==> $#"
 13 #判断参数的个数是否小于2个,若是则打印提示信息并退出程序
 14 [ $# -lt 2 ] && echo "The number of parameter is less than 2. Stop here." && exit 0
 15 #打印全部参数
 16 echo "Your whole parameter is ==> $@"
 17 #打印第一个参数
 18 echo "The 1st parameter ==> $1"
 19 #打印第二个参数
 20 echo "The 2nd parameter ==> $2"
 21 
 22 exit 0

在这里插入图片描述

 除此之外,还有一个偏移变量的命令shift,可以做偏移变量的操作,从右往左偏移,最左边的变量将会被移除。将上面的程序稍加修改一下:

  2 #!/bin/bash 
  3 
  4 # Program:
  5 #       This program shows script name,parameters.
  6 # History:
  7 # 2021/08/07 Zhengqing.Yang First release
  8 
  9 #输出脚本的文件名
 10 echo "The script name is ==> $0"
 11 
 12 #判断参数的个数是否小于2个,若是则打印提示信息并退出程序
 13 [ $# -lt 2 ] && echo "The number of parameter is less than 2. Stop here." && exit 0
 14 
 15 #打印第一次偏移之前的参数个数和全部参数
 16 echo "Total parameter number is ==> $#"
 17 echo "Your whole parameter is ==> $@"
 18 
 19 shift #第一偏移,默认移除第一个参数
 20 
 21 #打印第一次偏移之后的参数个数和全部参数
 22 echo "第一次偏移之后:"
 23 echo "Total parameter number is ==> $#"
 24 echo "Your whole parameter is ==> $@"
 25 
 26 shift 3 #第二次变量偏移,表示移除前面三个参数
 27 
 28 #打印第二次偏移之后的参数个数和全部参数
 29 echo "第二次偏移之后:"
 30 echo "Total parameter number is ==> $#"
 31 echo "Your whole parameter is ==> $@"
 32 
 33 exit 0

在这里插入图片描述

条件判断式

if…then

 类似c、c++、java语言,shell script也有if语句,只不过它们在形式上有所区别,在功能上完全一样。在shell script中,if判断式如下:

if [ 条件判断式一 ]; then
	当条件判断式一成立时,可以进行命令的工作内容;
elif [ 条件判断式二 ]; then
	当条件判断式二成立时,可以进行命令的工作内容;
else
	当条件判断式一和二都不成立时,可以进行命令的工作内容;
fi

将前面判断yn的程序使用if then改写一下会不会变得简单易读一些呢?

1 
  2 #!/bin/bash 
  3 
  4 # Program:
  5 #       This program shows the user's choice.
  6 # History:
  7 # 2021/08/05 Zhengqing.Yang First release
  8 
  9 #从标准输入读取字符串
 10 read -p "Please input (Y/N): " yn
 11 
 12 #判断是否输入 y或Y/n或N
 13 if [ "$yn" == "Y" ] || [ "$yn" == "y" ]; then
 14     echo "OK, continue"
 15     exit 0
 16 
 17 elif [ "$yn" == "N" ] || [ "$yn" == "n" ]; then
 18     echo "Oh, interrupt"
 19     exit 0
 20 else
 21     echo "I don't known what you choice is"
 22     exit 0
 23 fi

显然,这种格式接近于c语言以及其他高级语言的if判断式,对于我们来说很熟悉,程序简单易读,易懂,易理解。
 看书总结的过程中,看到一个例子觉得不错,它主要功能是计算士兵还有多久可以退伍的天数。正好我也有几个参军入伍的朋友,我们时常还存在着联系,正好借着学习一下这个程序的机会,算算还有多久能和这几个朋友一起喝酒。
 其实程序逻辑比较简单,首先让朋友输入一个退伍的日期,然后与现在的日期做减法运算。日期怎么做减法呢?将日期转换成秒数再相减,最后再把结果转换成天数就可以了。

 
  2 #!/bin/bash 
  3 
  4 # Program:
  5 #       You input your demobilization date.I calculate how many days
  6 #       before you demobilize.
  7 # History:
  8 # 2021/08/07 Zhengqing.Yang First release
  9 
 10 #打印提示信息,告知用户应该输入的日期格式
 11 read -p "Please input your demobilization date (format: 20090401):" date2
 12 
 13 #判断一下输入内容是否正确
 14 date_d=$(echo $date2 | grep '[0-9]\{8\}') #判断是否有连续的八个数字
 15 if [ "$date_d" == "" ]; then
 16     echo "You input the wrong date format"
 17     exit 1
 18 fi
 19 #开始计算日期
 20 
 21 #声明整型变量
 22 declare -i date_dem
 23 declare -i date_now
 24 declare -i date_total_s
 25 declare -i date_d
 26 declare -i date_h
 27 
 28 #计算
 29 date_dem=`date --date="$date2" +%s`#退伍日期秒数
 30 date_now=`date +%s`#当前日期的秒数
 31 date_total_s=$(($date_dem-$date_now))#日期之差
 32 date_d=$(($date_total_s/60/60/24))#转为天数
 34 #判断是否已经退伍
 35 if [ "$date_total_s" -lt "0" ]; then
 36     echo "You had been demobilization before: "$((-1*date_d))" ago"
 37 else
 38     date_h=$(($(($date_total_s-$date_d*60*60*24))/60/60))
 39     echo "You will demobilize after $date_d days and $date_h hours"
 40 fi
 41 exit 0
 42 
 

s h e l l 语 法 分 析 : \color{Crimson}{shell语法分析:} shell

  • `命令`
    这个语法与$(命令)的作用是一样,都是命令替换的,里面包含的命令可以在shell下单独执行。
  • [0-9]{8}
    判断一串字符串中是否包含连续8个数字。
  • declare -i
    在shell script中声明一个整型变量。

case…esac

 同样shell script中也有类似于c语言中的switch..case功能的语句,一般称它为开关语句,它在格式上跟switch..case大不一样,语法奇奇怪怪的。

case $变量的名称 in
	"第一个变量内容")
		程序段
		;;
	"第二个变量内容"
		程序段
		;;
	*)
	exit 1;
	;;
esac

 从上面的语法来看,case程序段是以case开头,esac结尾的。除此之外,每一个变量内容之后有一个右括号),并且程序段后面另起一行用双分号;来代表这个程序段的结束。
*)这个符号类似于switch...case里面的default,当输入的变量内容不符合第一个和第二个时,执行这一语句,我们通常可以用来告知用户一些提示信息。
 不妨用一个简单的程序来具体感受一下这个case程序段的用法。例如,从标准输入获取one/two/three,通过程序判断后输出。

1 
  2 #!/bin/bash 
  3 
  4 # Program:
  5 #       This script only accepts the flowing parameter:one,two or three.
  6 # History:
  7 # 2021/08/07 Zhengqing.Yang First release
  8 
  9 echo "This program will print your selection !"
 10 
 11 #从标准输入获取字符串
 12 read -p "Input your choice:" choice
 13 
 14 #开始判断
 15 case $choice in
 16     "one")
 17         echo "Your choice is ONE"
 18         ;;
 19     "two")
 20         echo "Your choice is TWO"
 21         ;;
 22     "three")
 23         echo "Your choice is THREE"
 24         ;;
 25     *)
 26         echo "Input error !"
 27         ;;
 28 esac
 29 
 30 exit 0

function 功能

 function功能其实就是函数功能,将一连串命令打包起来,类似自定义一个执行命令的东西,好处在于简化程序,增加shell脚本的可移植性,以于维护脚本,还可以用function功能自定义一些命令行模式下使用的命令。function的语法如下:

function fname()
{

}

和C语言中的函数定义很像,只不过在这里没有返回值和参数列表而已,虽然没有参数列表,但是可以传参。如何定义function和传参呢?

1 
  2 #!/bin/bash 
  3 # Program:
  4 #       Use function to repeat information.
  5 # History:
  6 # 2021/08/07 Zhengqing.Yang First release
  7 
  8 function printit()
  9 {
 10     echo "Your choice is $1"
 11 }
 12 
 13 echo "This program will print your selection !"
 14 
 15 read -p "Input your choice (one ,two or three): " choice
 16 
 17 case $choice in
 18     "one")
 19         printit "ONE"
 20         ;;
 21     "two")
 22         printit "TWO"
 23         ;;
 24     "three")
 25         printit "THREE"
 26         ;;
 27     *)
 28         echo "Input error !"
 29         ;;
 30 esac
 31 
 32 
 33 exit 0

function也有内置的变量,它与shell script很类似,$0代表函数名,$1$2$3…代表后面接的参数,这里特别要注意与shell script区分,它们的作用域不同。在上面的程序中,printit是函数名,“ONE”,"TWO"和"THREE"是传进去的参数,在printit函数体中,$1是接收参数的变量。
 在shell function中,也有关键字return,当函数调用结束时,可以返回一个值,若不显示return,则默认返回上一次命令的状态值。在function里,返回0代表执行成功,返回非0代表执行失败。
 在这里还想谈谈shell中变量的定义,在shell中,也有全局变量和局部变量之分:
 全局变量:在shell中定义的变量都是全局变量,其作用域从变量定义的地方开始,直到shell结束或者变量删除的地方。删除变量的语法是unset 变量
 局部变量:其实不管是在function之内还是之外定义的变量都属于全局变量,当在function内定义变量用local关键字声明时才是局部变量,其作用域仅限函数体内。如果在一个function中,局部变量和全局变量的名字相同,则只有局部变量生效。

循环

 常见的循环结构有三种,分别是while do doneuntil do donefor do done

  1. while do done结构
while [ 条件 ]
do
	程序段
done

 举个例子:计算1+2+3+…+100的值

#!/bin/bash 

# Program:
#       Use loop calculate "1+2+3+...+100" result.
# History:
# 2021/08/07 Zhengqing.Yang First release

declare -i result=0 #存放结果
declare -i i=0 #循环因子

while [ "$i" != "100" ]
do
    i=$(($i+1))
    result=$(($result+$i))
done

echo "The result of 1+2+3+...+100 is ==> $result"

exit 0

s h e l l 语 法 分 析 : \color{Crimson}{shell语法分析:} shell变量声明declare可以用也可以不用,declare主要用于声明变量并设置变量的属性和显示函数。当设置了属性之后,这个变量只能存储该类型的数据了,若不设置的话,这个变量可以存储任何类型的数值。显示函数是什么意思呢?就是在运行shell脚本的时候,将前面定义的function函数打印在屏幕上。

  1. until do done
until [ 条件 ]
do
	程序段
done

 until与while的区别:其实从中文意思上就可以理解,until中文译为直到...时候,在程序里边意思就是直到条件成立时才跳出循环,while中文译为当...的时候,意思是当条件成立时,执行循环,条件不成时,跳出循环。
 举个例子:输入一个值,计算从1累加到该值的结果,例如我输入10,计算1+2+3+…+10 的值。

#!/bin/bash 

# Program:
#       Until do done ---demo.
# History:
# 2021/08/07 Zhengqing.Yang First release

result=0
i=0

read -p "Please input one digit: " d

until [ "$i" == "$d" ]
do
    i=$(($i+1))
    result=$(($result+$i))
done

echo "The result is ==> $result"

exit 0
  1. for do done
     for循环有两种语法,第一种主要用于非数值处理,第二种主要用于数值处理,第二种类似于c语言里边的for循环。
     第一种语法如下:
for var in con1 con2 con3 ...
do
	程序段
done

var变量的内容在循环工作时,依次为con1 con2 con3…,在实际应用中我们一般不会这样写,因为灵活性不高,而且费体力。在一些需要循环100次的程序中,不会有人在后面写100个循环因子吧。那应该如何巧妙的使用这个语法呢,用两个例子进行说明吧。
 例子1:列出系统中所有账号的名称、标识符和特殊参数。

#!/bin/bash 

# Program:
#       for do done --demo 1.
# History:
# 2021/08/7 Zhengqing.Yang First release

users=$(cut -d ':' -f1 /etc/passwd) #获取所有的账户名称

for username in $users
do
    id $username
    finger $username
done

exit 0

s h e l l 语 法 分 析 : \color{Crimson}{shell语法分析:} shell

  • cut命令
    从文件的每一行剪切字符、字段、字节。cut -d ':' -f1 /etc/passwd,-d 指定分隔符,这里以:作为分隔符,-f1指剪切第一个域,最后的是文件名。
  • id命令
    用于显示用户ID,群组ID。
  • finger命令
    用户显示用户信息。

 例子2:ping测试局域网内的100台主机。

#!/bin/bash 

# Program:
#       This program shows "Hello world" in your screen.
# History:
# 2021/08/3 Zhengqing.Yang First release

network="192.168.172"

for sitenu in $(seq 1 100)
do
    #取得ping命令的回传值
    ping -c 1 -w 1 $network.$sitenu &> /dev/null && result=0 || result=1

    #判断各个主机是否连通
    if [ "$result" == 0 ]; then
        echo "Server $network.$sitenu is up"
    else
        echo "Server $network.$sitenu is down"
    fi
done

exit 0

s h e l l 语 法 分 析 : \color{Crimson}{shell语法分析:} shell

  • ping命令
    -c 1 发送一个数据包,-w 1 等待响应时间为1秒。
  • &> file
    将标准输出和标准错误重定向到file文件
  • && 和 || 一起连用
命令含义
[ -z “string” ] && echo 0 || echo 1若string位空,则执行echo 0,否则执行echo 1
[ -z “string” ] || echo 0 && echo 1若string位空,则执行echo 1,否则执行echo 0

 第二种语法如下:

for (( 初始值; 限制值; 执行步长 ))
do
	程序段
done

 shell script中的for循环在格式上比c语言的for循环多了一个括号而已,其功能以及括号中所表达的意思是一样的。这种语法适合用于数值方式的运算,可以简单改写一个程序感受一下。

#!/bin/bash 

# Program:
#       for do done --demo 2.
# History:
# 2021/08/08 Zhengqing.Yang First release

read -p "Please input a number,I will count for 1+2+3+...+your_input: " nu

result=0

for(( i=0; i<=$nu; i=i+1 ))
do
    result=$(($result+$i))
done

echo "The result of 1+2+3+...+$nu ==> $result"

exit 0

 程序实现的功能是累加计算,例如用户输入10,程序计算出1+2+3+…+10的结果。可以看到两种for循环的语法不同,应用场景也不同,在不同的场景下使用不同的语法会使程序更加简单易读。

文本处理

sed命令

 sed命令主要用于自动编辑一个或多个文件,每次处理一行内容,可以对文件进行替换、行新增、行删除、行选取等操作,简化对文件的反复操作。对文件处理的原理是将当前要处理的行保存在临时缓冲区,接着sed命令去处理缓冲区的内容,处理完后,将缓冲区的内容送往屏幕,接着再处理下一行,反反复复,直到文件结尾。关于sed的用法网上有很多介绍,这里不做总结。
 sed命令有两种语法,分别是:

  • sed [optiions] 'command' file
  • sed [options] -f scriptfile file:-f 添加脚本文件到运行列表

 关于详细的sed使用方法可以参考此贴:Linux sed命令示例解析

awk命令

 awk命令也是用于文本分析的工具,逐行读入,默认以空格、制表符为分隔符将每行切片,切开的部分再进行各种分析。但是它是一种编程语言,而sed是一种流编辑器。
 Linux下对文本的处理的工具还有grep,这三者搭配着正则表达式一起使用可以发挥出强大的作用。针对这三个工具更加详细的信息可以参考链接:Linux文本三剑客

shell script的追踪和调试

sh命令可以用来debug shell脚本,根据sh命令的选项可以追踪和调试程序,常用到几个sh命令选项如下:

  • -n :不要执行脚本,仅查询语法的问题
  • -v:在执行脚本前,先将脚本的内容打印到屏幕上
  • -x:将使用到脚本打印到屏幕上。
    在这里插入图片描述
     使用sh -n sh15.sh命令就可以检查脚本语法了,这里第13行有语法错误,意思是错误的循环变量。查看程序,果然如此,变量之前没带$。还有一个原因,ubuntu将默认的bash shell更换成了dash shell,dash shell 不支持这种语法的for循环。将它更换为bash shell就可以了,具体做法参考以下链接:
https://blog.csdn.net/liuqinglong_along/article/details/52191382
  • 1
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值