linux shell 脚本编程基本语法

linux shell脚本编程基本语法

Shell script是利用shell的功能所写的一个“程序”,这个程序是使用纯文本文件,将一些Linux Shell的语法与命令(含外部命令)写在里面,搭配正则表达式、管道命令与数据流重定向等功能,以达到我们所想要的处理目的。Shell script提供数组、循环、条件与逻辑判断等重要功能,让用户也可以直接以shell来编写程序,而不必使用类似C程序来完成相关功能。Shell Script就像是早期DOS年代的批处理文件(.bat)。

编程格式

在写C程序的时候,代码的开头我们通常会给版本信息。shell脚本也不例外。
一般声明如下。

#!/bin/sh
# Program:
#   This program shows "Hello World" in your srceen
# History:
#   2017-6-5 liwanneng  V1.0.0

echo -e "Hello world"
  • 第一行 #!/bin/sh 声明该shell script使用的shell名称,linux默认使用的是bash shell
  • 第二行Program后面是程序内容的说明,这个shellscript中,除了第一行外,其他#符号表示注释
  • 第四行History后面是时间,作者以及版本信息
  • 从echo开始,后面表示程序正文

shell script中常见语法

从屏幕中获取输入

在shell script中,使用read -p 来获取标准输入
例如

#!/bin/sh
# Program:
#   This program User input his first name and last name, Program shows his full name
# History:
#   2017-6-5 liwanneng  V1.0.0
read -p "Please input your first name:" firstname #提示用户输入,末尾的first为变量名
read -p "Please input your last name:" lastname 
echo -e "/nYour full name is :$firstname $lastname" #结果由屏幕输出

其输出结果如图
linux shell 脚本编程基本语法_第1张图片

数值运算,简单的加减乘除

在shell script脚本中,可以使用$( (计算式) )来进行整数数值运算

#!/bin/sh
# Program:
#   This program 
# History:
#   2017-6-5 liwanneng  V1.0.0

echo -e "Please Input TWO numbers\n"
read -p "the first number is:" num1#提示用户输入,末尾的num1为变量名
read -p "the second number is:" num2
product=$(($num1*$num2)) 
sum=$(($num1+$num2)) 
red=$(($num1-$num2)) 
div=$(($num1/$num2)) 
echo -e "$num1 x $num2 = $product"
echo -e "$num1 + $num2 = $sum"
echo -e "$num1 - $num2 = $red"
echo -e "$num1 ÷ $num2 = $div"

结果:
linux shell 脚本编程基本语法_第2张图片

shell script中的默认变量($0, $1…)

在bashshell中,$0表示脚本程序本身,$1表示脚本程序后面跟的第一个参数,以此类推,$2表示脚本程序后面跟的第二个参数。除了这些数字变量之外,还有一些较为特殊的变量可以在script中使用来调用这些参数。
* $#:表示脚本程序后面跟的参数个数
* \$@:表示 “\$1”, “\$2”, “\$3”之意,每个变量是独立的。
* \$*:表示”\$1c\$2c\$3”,其中c为分隔字符,默认为空格键。
来看个例子

#!/bin/sh
# Program
#   Program shows script name, paramters...
# History
#   2017-6-4
echo -e "The script name is $0"
echo -e "Total parameter numher is $#"
[ "$#" -lt 2 ] && echo -e "The number of paramter is less than 2. Stop here.    " && exit 0
echo -e "Your whole paramter is $@"
echo -e "Your first paramter is $1"
echo -e "Your second paramter is $2"

执行结果
linux shell 脚本编程基本语法_第3张图片

shell script中的判断

test命令的测试

在linux中,可以使用test命令来测试系统上面某些文件的相关属性。例如,我要检查sh01.sh是否存在使用:test -e ./sh01.sh
单独执行该命令不会显示任何结果,我们可以在后面加上&&以及||来显示结果,如图:
这里写图片描述
其中 test命令后面跟的 -e表示:判断文件是否存在。除了-e外,test还可以跟其他许多的参数来获取文件或变量的相关属性如

  • 关于某个文件名的文件类型判断,如 test -e filename
    -e:该文件名是否存在
    -f:该文件名是否存在且为文件
    -d:该文件名是否存在且为目录
    -b:该文件名是否存在且为块设备文件
    -c:该文件名是否存在且为字符设备文件
    -S:该文件名是否存在且为socket文件(大写S)
    -p:该文件名是否存在且为FIFO文件
    -L:该文件名是否存在且为链接文件
  • 关于文件的权限检测,如test -r filename
    -r:该文件名是否存在且具有“可读”权限
    -w:该文件名是否存在且具有“可写”权限
    -x:该文件名是否存在且具有“可执行”权限
    -u:该文件名是否存在且具有“SUID”属性
    -g:该文件名是否存在且具有“SGID”属性
    -k:该文件名是否存在且具有“sticky bit”属性
    -s:该文件名是否存在且为“非空白文件”(小写s)
  • 两个文件之间的比较,如:test file1 -nt file2
    -nt:newer than,判断file1是否比file2新
    -ot:older than,判断file1是否比file2旧
    -ef:判断file1与file2是否为同一文件,可用在判断hard link的判定上。主要意义在于判定两个文件是否指向统一个inode
  • 关于两个整数之间的判定,如test num1 eq num2
    -eq:equal,num1等于num2
    -ne:not equal,num1不等于num2
    -gt:greater than,num1大于num2
    -lt:less than,num1小于num2
    -ge:great equal,num1大于等于num2
    -le:less equal,num1小于等于num2
  • 判定字符串的数据
    test -z string:判定字符串是否为0,若string为空字符串,则为true
    test -n string:判定字符串是否为非零,若string为空字符串,则为false
  • 多重条件判定,例如:test -r filename -a -x filename
    -a:两个条件同时成立!例如 test -r file -a -xfile,则file同时具有 r 与 x 权限时,才回传true
    -o:任何一个条件成立!例如 test -r file -o -x file,则file具有 r 或者 x 权限时,才回传true
    !:反向状态!如test !-x file,当file不具有x时,回传true。

利用判断符号[]

除了利用test命令判断外,我们可以利用判断符号“[]”(英文输入状态下的中括号)来进行数据的判断。这个符号在shell script中经常与if条件判断搭配使用。
在bash的语法中使用“[]”做判断必须要注意的几点
1. 中括号两端需要空格符来分隔
2. 在中括号[]内每个组件都需要有空格来分隔
3. 中括号内的变量和常量最好都用双引号括起来

假如我空格号使用“口”符号来表示,那么在这些地方需要有空格。

口[口"$HOME"口==口"$MAIL"口]口

上面这句话的意思是变量HOME与变量MAIL是否相同的意思,相当于test$HOME=$MAIL

条件判断式

if… then是shell script中常用到的条件判断式。简单来说就是当符合某项条件的时候,就进行某项工作。其格式一般为

if [ 条件1 ] ; then
   程序段
#在shell script中用elif,功能类似于C语言中的else if语句
elif [ 条件2 ]; then
   程序段
else
   程序段
fi   #fi表示if的结束

下面来看一个例子

 #!/bin/sh
 # Program
 #   This program shows user's choice
 # History
 #   2017-6-4 liwanneng V1.0.0
read -p "Please input Y/N:" yn
if [ "$yn" == "Y" ] || [ "$yn" == "y" ]; then
      echo "Clever boy! You will Continue"
      exit 0
elif [ "$yn" == "N" ] || [ "$yn" == "n" ]; then
      echo "You will interrupt the program!!!"
      exit 0
else
      echo "Please input Y/y or N/n!"
      exit 0
fi

运行结果如下:
linux shell 脚本编程基本语法_第4张图片

利用case…esac判断

在shell script中除了用if…then语句来判断,我们还可以使用case…esac来表示多重条件判断,类似于C语言中的Case语句。其格式为:

case $变量名称 in  #关键字为case,还有$符号
   "第一个变量内容") #每个变量内容用括号括起来,关键字则为小括号
      程序段
      ;;  #每个类型的结尾使用英文输入法状态下的两个分号来表示
   "第二个变量内容")
      程序段
      ;;
   *) #最后一个变量使用*来表示其他值
      exit 1
      ;;
easc  #由esac来表示case语句的最终结尾

来看一个例子

 #!/bin/sh
   # Program
   #   Program show "hello" from $1...by using case ...esac
   # History
   # 2017-6-4 10:32:33

   case $1 in
       "hello")
           echo "Hello,how are you!"
          ;;
      "bye")
          echo "bye-bye!"
          ;;
      "") #如果没有输入
          echo "You must input parameter, ex> {$0 someword}"
          ;;
      *)
          echo "use $0 {hello or bye}"
          ;;
  esac

来看程序执行的结果
linux shell 脚本编程基本语法_第5张图片

whlie do done,until do done 不定循环

在C语言中,经常用到whle循环和for循环来表示程序的反复执行。在shell script中同样有while循环和for循环,只是shell script 中的while和for 的用法与C语言中稍有不同。

while do done不定循环

在shell script中while…done不定循环的常见格式如下

while [ condition ] #中括号内的状态就是判断式   
do #do是循环的开始
done  #done是循环的结束

while的在英语中的意思是“当…时”,所以while…done这种循环表示当condition条件成立时就进行循环,直到condition条件不成立时才停止循环。
来看一个例子

  #!/bin/sh
   # Program
   #   Repet quesstion until input correct answer.
   # History
   #   2017-6-6 liwanneng V1.0.0

  while [ "$yn" != "yes" -a "$yn" != "YES" ]
  do
       read -p "Please input yes/YES to stop this program:" yn
  done
  echo -e "OK,you input the correct answer."

上面这个程序为:当满足条件 “$yn” != “yes” -a “$yn” != “YES” 即输入不为yes/YES时,程序一直循环,调用read语句一直等待用户输入。当不满足条件 “$yn” != “yes” -a “$yn” != “YES” 即输入为yes/YES时,程序退出循环,调用echo语句。程序执行结果如图。
linux shell 脚本编程基本语法_第6张图片

until do done不定循环

在shell script中还有一种不定循环 until do done循环,这种循环恰恰与while相反,它是当条件成立时才进行循环,条件不成立时,程序退出循环。其一般格式如下

ubtil [ condition ]
do
    程序段
done 

同样来看一个例子

#!/bin/sh
# Program
#   Repeat question ubtil user input correct answer
# History
#   2017-6-6 liwanneng V1.0.0

until [ "$yn" == "yes" -o "$yn" == "YES" ]
do
  read -p "Please input yes/YES to stop the program:" yn
done
echo -e "Ok,you input correct answer."

程序执行结果和上面有while循环的程序执行结果一样。但是程序逻辑却有所区别。当不满足条件”$yn” == “yes” -o “$yn” == “YES” 即输入不为yes或YES的时候,程序一直循环,调用read语句等待用户输入。直到满足条件 “$yn” == “yes” -o “$yn” == “YES” 即输入为yes 或 YES的时候,程序退出循环,执行echo语句。
linux shell 脚本编程基本语法_第7张图片

for … do … done固定循环以及数值处理

相对于while,until的循环方式是必须要“符合某个条件”,for循环则是“已经知道要循环几次”的状态。它的语法是

for var in con1 con2 con3 #var为变量,con1,con2,con3分别为条件1,条件2,条件3
do
    程序段
done

上面这段例子的意思是,当变量 var1. var的内容为con1
2. 第二次循环时, varcon23. var的内容为con3

来看一个具体的例子,加入有三种动物分别是cat,dog,bird,每一行都输出一种动物,程序可以写为:

#!/bin/sh
# Program 
#   Using for ...loop to print 3 animal
# History
#   2017-6-6 liwanneng V1.0.0
for animal in dog cat bird
do
    echo "There is ${animal}..."
done

程序执行结果如下
这里写图片描述

for… do… done的数值处理

除了上面的方法外,for循环还有另外一种写法,也就是C语言中for循环的用法,语句如下:

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

for后面三串内容的意义:
1. 初始值:某个变量在循环中的初始值,比如常见的 i=1;
2. 限定值:当变量在限定值范围之内,程序一直循环直到超出限定值,如 i<=100;
3. 执行步长:没做一次循环的变化量,如i = i+1;
来看一个具体的例子,输入一个数字num,程序做1+2+3…+num运算

#!/bin/sh
# Program
#   Caculate 1+2+3+...$(input)
# HIstory
#   2017-6-6 liwanneng V1.0.0
read -p "Please input a num:" num
for(( i=1; i<$num; i=i+1 ))
do
    sum=$(($sum+$i))
done
echo "The result of 1+2+3+...$num is:$sum" 

来看程序执行结果
linux shell 脚本编程基本语法_第8张图片

function函数功能

在C语言中我们经常自己封装函数来表示执行同样功能的一段代码,在shell script中同样有function功能。其一般格式为

function fname(){
 程序段
}

fname为封装函数的名字,需要注意的是在shell script中不能像C语言一样现在调用函数之前声明,然后可在调用函数之后实现其内容,而只能在调用fname之前就要实现其内容。话不多说,来看例子

#!/bin/sh
# Program
# Use function to repeat information
# History
# 2017-6-6 liwanneng V1.0.0
function printit(){
    echo -n "Your choice is :" #加上-n可以不断行继续在同一行显示
}

echo "This program will print your selection."
case $1 in
"one")
     printit;echo $1 | tr 'a-z' 'A-Z'#将小写转换成大写
     ;;
 "two")
     printit;echo $1 | tr 'a-z' 'A-Z'
     ;;
 "three")
     printit;echo $1 | tr 'a-z' 'A-Z'
     ;;
 *)
     echo "Usage $0 {one|two|three}"
     ;;
  esac

程序执行结果:
linux shell 脚本编程基本语法_第9张图片

shell script的追踪与调试

是程序就一定有bug,如果程序出了错,在C语言中我们又自己的调试方法。在shell script中有没有办法调试程序呢,答案是有的。我们可以直接以bash的相关参数来进行判断。sh -n/v/x script.sh

  • -n:不要执行script,仅查询语法是否正确
  • -v:执行script之前,先将script的内容输出到屏幕
  • -x:将使用到的script内容显示到屏幕上(经常用到)

懂了以上这些shell脚本编程语法,一般的shell脚本程序看懂应该没问题了。但是要想自己会写shell脚本程序,还得多加练习!多加练习!多加练习!

你可能感兴趣的:(linux学习笔记)