Linux-03shell语法3

  • Linux-03shell语法3已关闭评论
  • 88 次浏览
  • A+
所属分类:linux技术
摘要

类似于C/C++中的switch语句。命令格式当条件为真时结束。命令格式:跳出当前一层循环,注意与C/C++不同的是:break不能跳出case语句。


判断语句

if…then形式

  • 类似于C/C++中的if-else语句。

单层if

  • 命令格式:
if condition then     语句1     语句2     ... fi 
  • 示例:
a=3 b=4  if [ "$a" -lt "$b" ] && [ "$a" -gt 2 ] then     echo ${a}在范围内 fi 
  • 输出结果:
3在范围内 

单层if-else

  • 命令格式
if condition then     语句1     语句2     ... else     语句1     语句2     ... fi 
  • 示例:
a=3 b=4  if ! [ "$a" -lt "$b" ] then     echo ${a}不小于${b} else     echo ${a}小于${b} fi 
  • 输出结果:
3小于4 

多层if-elif-elif-else

  • 命令格式
if condition then     语句1     语句2     ... elif condition then     语句1     语句2     ... elif condition then     语句1     语句2 else     语句1     语句2     ... fi 
  • 示例:
a=4  if [ $a -eq 1 ] then     echo ${a}等于1 elif [ $a -eq 2 ] then     echo ${a}等于2 elif [ $a -eq 3 ] then     echo ${a}等于3 else     echo 其他 fi 
  • 输出结果:
其他 

case…esac形式

  • 类似于C/C++中的switch语句。

  • 命令格式

case $变量名称 in     值1)         语句1         语句2         ...         ;;  # 类似于C/C++中的break     值2)         语句1         语句2         ...         ;;     *)  # 类似于C/C++中的default         语句1         语句2         ...         ;; esac 
  • 示例:
a=4  case $a in     1)         echo ${a}等于1         ;;     2)         echo ${a}等于2         ;;     3)         echo ${a}等于3         ;;     *)         echo 其他         ;; esac 
  • 输出结果:
其他 

循环语句

for…in…do…done

  • 命令格式:
for var in val1 val2 val3 do     语句1     语句2     ... done 
  • 示例1,输出a 2 cc,每个元素一行:
for i in a 2 cc do     echo $i done 
  • 示例2,输出当前路径下的所有文件名,每个文件名一行:
for file in `ls` do     echo $file done 
  • 示例3,输出1-10
for i in $(seq 1 10) do     echo $i done 
  • 示例4,使用{1..10} 或者
for i in {a..z} do     echo $i done 

for ((…;…;…)) do…done

  • 命令格式:
for ((expression; condition; expression)) do     语句1     语句2 done 
  • 示例,输出1-10,每个数占一行:
for ((i=1; i<=10; i++)) do     echo $i done 

while…do…done循环

  • 命令格式:
while condition do     语句1     语句2     ... done 
  • 示例,文件结束符为Ctrl+d,输入文件结束符后read指令返回false。
while read name do     echo $name done 

until…do…done循环

  • 当条件为真时结束。

  • 命令格式:

until condition do     语句1     语句2     ... done 
  • 示例,当用户输入yes或者YES时结束,否则一直等待读入。
until [ "${word}" == "yes" ] || [ "${word}" == "YES" ] do     read -p "Please input yes/YES to stop this program: " word done 

break命令

  • 跳出当前一层循环,注意与C/C++不同的是:break不能跳出case语句。

  • 示例

while read name do     for ((i=1;i<=10;i++))     do         case $i in             8)                 break                 ;;             *)                 echo $i                 ;;         esac     done done 
  • 该示例每读入非EOF的字符串,会输出一遍1-7。
  • 该程序可以输入Ctrl+d文件结束符来结束,也可以直接用Ctrl+c杀掉该进程。

continue命令

  • 跳出当前循环。

  • 示例:

for ((i=1;i<=10;i++)) do     if [ `expr $i % 2` -eq 0 ]     then         continue     fi     echo $i done 
  • 该程序输出1-10中的所有奇数。

死循环的处理方式

  • 如果AC Terminal可以打开该程序,则输入Ctrl+c即可。

  • 否则可以直接关闭进程:

    • 使用top命令找到进程的PID
    • ps aux返回当前打开的所有进程
    • 输入kill -9 PID即可关掉此进程

函数

概述

  • bash中的函数类似于C/C++中的函数,但return的返回值与C/C++不同,返回的是exit code,取值为0-255,0表示正常结束。

  • 如果想获取函数的输出结果,可以通过echo输出到stdout中,然后通过$(function_name)来获取stdout中的结果。

  • 函数的return值可以通过$?来获取。

  • 命令格式:

[function] func_name() {  # function关键字可以省略     语句1     语句2     ... } 

不获取 return值和stdout值

  • 示例
func() {     name=yxc     echo "Hello $name" }  func 
  • 输出结果:
Hello yxc 

获取 return值和stdout值

  • 不写return时,默认return 0。

  • 示例

func() {     name=yxc     echo "Hello $name"      return 123 }  output=$(func) ret=$?  echo "output = $output" echo "return = $ret" 
  • 输出结果:
output = Hello yxc return = 123 

函数的输入参数

  • 在函数内,$1表示第一个输入参数,$2表示第二个输入参数,依此类推。

  • 注意:函数内的$0仍然是文件名,而不是函数名。

  • 示例:

func() {  # 递归计算 $1 + ($1 - 1) + ($1 - 2) + ... + 0     word=""     while [ "${word}" != 'y' ] && [ "${word}" != 'n' ]     do         read -p "要进入func($1)函数吗?请输入y/n:" word     done      if [ "$word" == 'n' ]     then         echo 0         return 0     fi      if [ $1 -le 0 ]     then         echo 0         return 0     fi 	 	# $()会读取函数的stdout而不直接输出出来     sum=$(func $(expr $1 - 1)) 	# 只在最后一层输出函数的stdout     echo $(expr $sum + $1) }  echo $(func 10) 
  • 输出结果:
55 

函数内的局部变量

  • 可以在函数内定义局部变量,作用范围仅在当前函数内。

  • 可以在递归函数中定义局部变量。

  • 命令格式:

local 变量名=变量值 
  • 例如:
#! /bin/bash  func() {     local name=yxc     echo $name } func  echo $name 
  • 输出结果:
yxc 
  • 第一行为函数内的name变量,第二行为函数外调用name变量,会发现此时该变量不存在。

exit命令

  • exit命令用来退出当前shell进程,并返回一个退出状态;使用$?可以接收这个退出状态。

    • return和exit的共同之处都是返回exit code
    • 区别是return结束当前函数,exit结束整个shell脚本
  • exit命令可以接受一个整数值作为参数,代表退出状态。如果不指定,默认状态值是 0。

  • exit退出状态只能是一个介于 0~255 之间的整数,其中只有 0 表示成功,其它值都表示失败。

  • 示例:

  • 创建脚本test.sh,内容如下:

#! /bin/bash  if [ $# -ne 1 ]  # 如果传入参数个数等于1,则正常退出;否则非正常退出。 then     echo "arguments not valid"     exit 1 else     echo "arguments valid"     exit 0 fi 
  • 执行该脚本:
acs@9e0ebfcd82d7:~$ chmod +x test.sh acs@9e0ebfcd82d7:~$ ./test.sh acwing arguments valid acs@9e0ebfcd82d7:~$ echo $?  # 传入一个参数,则正常退出,exit code为0 0 acs@9e0ebfcd82d7:~$ ./test.sh arguments not valid acs@9e0ebfcd82d7:~$ echo $?  # 传入参数个数不是1,则非正常退出,exit code为1 1 

文件重定向

概述

  • 每个进程默认打开3个文件描述符:

    • stdin标准输入,从命令行读取数据,文件描述符为0
    • stdout标准输出,向命令行输出数据,文件描述符为1
    • stderr标准错误输出,向命令行输出数据,文件描述符为2
  • 可以用文件重定向将这三个文件重定向到其他文件中。

重定向命令列表

命令 说明
command > file 将stdout重定向到file中
command < file 将stdin重定向到file中
command >> file 将stdout以追加方式重定向到file中
command n> file 将文件描述符n重定向到file中
command n>> file 将文件描述符n以追加方式重定向到file中

输入和输出重定向

# ls -l > 文件 (列表的内容写入文件a.txt中 覆盖写) # ls -al >> 文件 (列表的内容文件追加到文件aa.txt的末尾)  # cat 文件1 > 文件2 (将文件1的内容覆盖到文件2)  # echo "内容" >> 文件 (将echo的内容追加到文件末尾) echo -e "Hello c" > output.txt  # 将stdout重定向到output.txt中 echo "World" >> output.txt  # 将字符串追加到output.txt中  read str < output.txt  # 从output.txt中读取字符串  echo $str  # 输出结果:Hello World 

同时重定向stdin和stdout

  • 创建bash脚本:
#! /bin/bash  read a read b  echo $(expr "$a" + "$b") 
  • 创建input.txt,里面的内容为:
3 4 
  • 执行命令:
acs@9e0ebfcd82d7:~$ chmod +x test.sh  # 添加可执行权限 acs@9e0ebfcd82d7:~$ ./test.sh < input.txt > output.txt  # 从input.txt中读取内容,将输出写入output.txt中 acs@9e0ebfcd82d7:~$ cat output.txt  # 查看output.txt中的内容 7 

引入外部脚本

概述

  • 类似于C/C++中的include操作,bash也可以引入其他文件中的代码。

  • 语法格式:

. filename  # 注意点和文件名之间有一个空格  或  source filename  # 引入的文件可以添加路径,比如使用绝对路径 source /home/acs/test1.sh 

示例

  • 创建test1.sh,内容为:
#! /bin/bash  name=yxc  # 定义变量name 
  • 然后创建test2.sh,内容为:
#! /bin/bash  source test1.sh # 或 . test1.sh  echo My name is: $name  # 可以使用test1.sh中的变量 
  • 执行命令:
acs@9e0ebfcd82d7:~$ chmod +x test2.sh acs@9e0ebfcd82d7:~$ ./test2.sh My name is: yxc