东吴 发表于 2024-4-1 16:16:19

关于shell脚本的学习

本帖最后由 东吴 于 2024-4-1 16:16 编辑

一、shell入门简介1.1shell概述Shell本身是一个用C语言编写的程序,它是用户使用Linux的桥梁。Shell既是一种命令语言,又是一种程序设计语言。作为命令语言,它交互式地解释和执行用户输入的命令;作为程序设计语言,它定义了各种变量和参数,并提供了许多在高级语言中才具有的控制结构,包括循环和分支。它虽然不是Linux系统核心的一部分,但它调用了系统核心的大部分功能来执行程序、建立文件并以并行的方式协调各个程序的运行。因此,对于用户来说,shell是最重要的实用程序,深入了解和熟练掌握shell的特性极其使用方法,是用好Linux系统的关键。
可以说,shell使用的熟练程度反映了用户对Linux使用的熟练程度。
1.2几种常见的Shell前面提到过,Shell是一种脚本语言,那么,就必须有解释器来执行这些脚本。Linux上常见的Shell脚本解释器有bash、sh、ash、csh、ksh,习惯上把它们称作一种Shell。我们常说有多少种Shell,其实说的是Shell脚本解释器。bash:是Linux系统默认使用的shell。bash由Brian Fox和Chet Ramey共同完成,是BourneAgain Shell的缩写,内部命令一共有40个。Linux使用它作为默认的shell是因为它有诸如以下的特色:•可以使用类似DOS下面的doskey的功能,用方向键查阅和快速输入并修改命令。•自动通过查找匹配的方式给出以某字符串开头的命令。•包含了自身的帮助功能,你只要在提示符下面键入help就可以得到相关的帮助。sh:由Steve Bourne开发,是Bourne Shell的缩写,各种UNIX系统都配有sh。ash:是由Kenneth Almquist编写的,Linux中占用系统资源最少的一个小shell,它只包含24个内部命令,因而使用起来很不方便。csh:是Linux比较大的内核,它由以William Joy为代表的共计47位作者编成,共有52个内部命令。该shell其实是指向/bin/tcsh这样的一个shell,也就是说,csh其实就是tcsh。ksh:是Korn shell的缩写,由Eric Gisin编写,共有42条内部命令。该shell最大的优点是几乎和商业发行版的ksh完全兼容,这样就可以在不用花钱购买商业版本的情况下尝试商业版本的性能了。
1.3第一个shell脚本1、需求:创建一个Shell脚本,输出helloworld2、案例实操:touch Helloworld.shvim Helloworld.sh在Helloworld.sh中输入如下内容
chmod +x Helloworld.sh#使脚本具有执行权限./Helloworld.sh#执行脚本3、脚本的常用执行方式第一种:采用bash或sh+脚本的相对路径或绝对路径(不用赋予脚本+x权限)sh+脚本的相对路径sh Helloworld.sh Hello world!   sh+脚本的绝对路径sh /home/uisrc/Helloworld.sh Hello world!   bash+脚本的相对路径bash Helloworld.sh Hello world!bash+脚本的绝对路径bash /home/uisrc/Helloworld.sh Hello world!第二种:采用输入脚本的绝对路径或相对路径执行脚本(必须具有可执行权限+x)首先要赋予Helloworld.sh 脚本的+x权限chmod 777 Helloworld.sh执行脚本相对路径./Helloworld.sh Hello world!绝对路径/home/uisrc/helloworld.sh Hello world!   注意:第一种执行方法,本质是bash解析器帮你执行脚本,所以脚本本身不需要执行权限。第二种执行方法,本质是脚本需要自己执行,所以需要执行权限。
二、shell环境变量2.1shell系统变量1. 常用系统变量$HOME、$PWD、$SHELL、$USER等2.案例实操(1)查看系统变量的值echo $HOME/root(2)显示当前Shell中所有变量:setsetBASH=/bin/bashBASH_ALIASES=()BASH_ARGC=()BASH_ARGV=()
2.2 自定义变量1.基本语法(1)定义变量:变量=值 (2)撤销变量:unset 变量(3)声明静态变量:readonly变量(注意:不能unset)2.变量定义规则(1)注意,变量名和等号之间不能有空格,这可能和你熟悉的所有编程语言都不一样。同时,变量名的命名须遵循如下规则:(2)只包含字母、数字和下划线:变量名可以包含字母(大小写敏感)、数字和下划线,不能包含其他特殊字符。(3)不能以数字开头:变量名不能以数字开头,但可以包含数字。(4)避免使用 Shell 关键字:不要使用Shell的关键字(例如 if、then、else、fi、for、while 等)作为变量名,以免引起混淆。(5)使用大写字母表示常量:习惯上,常量的变量名通常使用大写字母,例如PI=3.14。(6)避免使用特殊符号:尽量避免在变量名中使用特殊符号,因为它们可能与 Shell 的语法产生冲突。(7)避免使用空格:变量名中不应该包含空格,因为空格通常用于分隔命令和参数。3.案例实操(1)定义变量AA=5echo $A输出结果为:5(2)给变量A重新赋值A=8echo $A输出结果为:8(3)撤销变量Aunset Aecho $A (4)声明静态的变量B=2,不能unsetreadonly B=2echo $B输出结果为:2
B=9输出结果为:bash: B: readonly variable (5)在bash中,变量默认类型都是字符串类型,无法直接进行数值运算C=1+2echo $C输出结果为:1+2(6)变量的值如果有空格,需要使用双引号或单引号括起来D=I love you输出结果为:-bash: world: command not foundD="I love you"echo $A输出结果为:I love you(7)可把变量提升为全局环境变量,可供其他Shell程序使用export变量名vim helloworld.sh在helloworld.sh文件中增加echo $B 输出结果为./helloworld.sh Hello world!发现并没有打印输出变量B的值。export B./helloworld.sh 输出结果为:helloworld2
2.3 特殊变量:$n1.基本语法$n(功能描述:n为数字,$0代表该脚本名称,$1-$9代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如${10})2.案例实操输出该脚本文件名称、输入参数1和输入参数2 的值touch parameter.sh vim parameter.sh
#!/bin/bashecho "$0$1   $2"
chmod 777 parameter.sh./parameter.sh xxx zz输出结果为:./parameter.sh xxx zz 2.4 特殊变量:$#1.基本语法$#      (功能描述:获取所有输入参数个数,常用于循环)。2.案例实操获取输入参数的个数vim parameter.sh
#!/bin/bashecho "$0$1   $2"echo $#chmod 777 parameter.sh./parameter.sh xxx zz输出结果为:parameter.sh xxx zz 2 2.5 特殊变量:$*、$@1.基本语法$*(功能描述:这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体)$@(功能描述:这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待)2.案例实操打印输入的所有参数vim parameter.sh
#!/bin/bashecho "$0$1   $2"echo $#echo $*echo $@
./parameter.sh xxx yyy zzz输出结果为:parameter.sh xxx yyy3xxx yyy zzzxxx yyy zzz 2.6 特殊变量:$?1.基本语法功能描述:最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了。2.案例实操判断helloworld.sh脚本是否正确执行vim parameter.sh
      #!/bin/bash      echo "$0$1   $2"      echo $#      echo $*      echo $@
      ./parameter.sh xxx yyy zzz   输出结果为:      parameter.sh xxx yyy      3      xxx yyy zzz      xxx yyy zzz三 、shell基本运算符3.1算术运算符
运算符说明
+对两个变量做加法
-对两个变量做减法
*对两个变量做乘法
/对两个变量做除法
**对两个变量做幂运算
%取模运算,第一个变量除以第二个变量求余数
+=加等于,在自身基础上加第二个变量
-=减等于,在第一个变量的基础上减去第二个变量
*=乘等于,在第一个变量的基础上乘以第二个变量
/=除等于,在第一个变量的基础上除以第二个变量
%=取模赋值,第一个变量对第二个变量取模运算,再赋值给第一个变量

在shell中有三种方法可以更改运算顺序:1、用expr改变运算顺序。可以用echo `expr 1 + 2`来输出1+2的结果,用expr表示后面的表达式为一个数学运算。需要注意的是,`并不是一个单引号,而是“Tab”键上面的那个符号。2、用let指示数学运算。可以先将运算的结果赋值给变量b,运算命令是b=let1 + 2。然后用echo $b来输出b的值。如果没有let,则会输出1+2。3、用$[]表示数学运算。将一个数学运算写到$[]符号的中括号中,中括号中的内容将先进行数学运算(中括号中可以包含空格)。例如命令echo $,将输出结果3。3.2关系运算符
运算符说明
-eq检测两个数是否相等,相等返回 true
-ne检测两个数是否不相等,不相等返回 true
-gt检测左边的数是否大于右边的,如果是,则返回 true
-lt检测左边的数是否小于右边的,如果是,则返回 true
-ge检测左边的数是否大于等于右边的,如果是,则返回 true
-le检测左边的数是否小于等于右边的,如果是,则返回 true
输入test 1 -lt 2 && echo "yes"则打印yes
3.3布尔运算符
运算符说明举例
-a(and)与运算,两状况同时成立test -r file -a -x file,则file同时具有r和x权限时,才为true
-o(or)或运算,两状况任何一个成立test -r file -o -x file,则file具有r或x权限时,就为true。

!非运算,相反状态test!-r file,当file不具有r权限时,就为true

3.4逻辑运算符
运算符说明
&&逻辑的AND
||逻辑的OR

3.5字符串运算符
运算符说明
=两个字符串相等

!=两个字符串不相等

-z空串
-n非空串
$检测字符串是否不为空,不为空返回true

输入test "a" = "a" && echo "yes"则打印yes
3.6文件测试运算符
运算符说明
-b检测文件是否是块设备文件
-c检测文件是否是字符设备文件
-d检测文件是否是目录
-f测文件是否是普通文件(既不是目录,也不是设备文件)
-g检测文件是否设置了 SGID 位
-k检测文件是否设置了粘着位(Sticky Bit)
-p检测文件是否是有名管道
-u检测文件是否设置了 SUID 位
-r检测文件是否可读
-w检测文件是否可写
-x检测文件是否可执行
-s检测文件是否为空(文件大小是否大于0)
-e检测文件(包括目录)是否存在

四、shell流程编程控制语句4.1 if 判断1、基本语法 (1)单分支    if [ 条件判断式 ];then   程序     fi    或者     if [ 条件判断式 ]       then    程序       fi (2)多分支if [ 条件判断式 ]then程序elif [ 条件判断式 ]then程序else程序fi注意事项: ①[ 条件判断式 ],中括号和条件判断式之间必须有空格 ②if 后要有空格 2、案例实操 输入一个数字,如果是 1,则输出xxx zhen shuai,如果是 2,则输出 xxx zhen mei,如果是其它,什么也不输出。 touch if.sh vim if.sh
#!/bin/bashif [ $1 -eq 1 ]thenecho "xxx zhen shuai"elif [ $1 -eq 2 ]thenecho "xxx zhen mei"fi
chmod 777 if.sh./if.sh 1输出结果为:xxx zhen shuai./if.sh 2输出结果为:Xxx zhen mei
4.2 case 语句 1、基本语法case $变量名 in"值 1")如果变量的值等于值 1,则执行程序 1;;"值 2")如果变量的值等于值 2,则执行程序 2;;…省略其他分支…*)如果变量的值都不是以上的值,则执行此程序;;esac注意事项: (1)case 行尾必须为单词“in”,每一个模式匹配必须以右括号“)”结束。 (2)双分号“;;”表示命令序列结束,相当于 java 中的 break。 (3)最后的“*)”表示默认模式,相当于 java 中的 default。 2、案例实操 输入一个数字,如果是 1,则输出 xxx,如果是 2,则输出 yyy,如果是其它,输出zzz。 touch case.sh vim case.sh
#!/bin/bash case $1 in "1") echo "xxx" ;; "2") echo "yyy" ;; *) echo "zzz" ;; esac
chmod 777 case.sh ./case.sh 1 输出结果为:xxx./case.sh 2输出结果为:yyy./case.sh 3输出结果为:zzz4.3 for 循环 1、基本语法 1 for (( 初始值;循环控制条件;变量变化 )) do 程序 done 案例实操 :从 1 加到 100 touch for1.sh vim for1.sh
#!/bin/bash sum=0 for(( i=0;i<=100;i++ )) do sum=$[$sum+$i] done echo “sum=$sum”
chmod 777 for1.sh ./for1.sh 输出结果为sum=5050 2、基本语法 2 for 变量 in 值 1 值 2 值 3… do 程序 done 案例实操 (1)打印所有输入参数 touch for2.sh vim for2.sh
#!/bin/bash #打印数字 for i in aa bb cc do echo "xxx love $i" done chmod 777 for2.sh ./for2.sh 输出结果为:xxx love aa xxx love bb xxx love cc (2)比较$*和$@区别 $*和$@都表示传递给函数或脚本的所有参数,不被双引号“”包含时,都以$1 $2 …$n的形式输出所有参数。 touch for3.sh vim for3.sh

#!/bin/bash echo '=============$*=============' for i in $* do echo "xxx love $i" done echo '=============$@=============' for j in $@ do echo "xxx love $j" done

chmod 777 for3.sh ./for3.sh cls mly wls 输出结果为:=============$*============= xxx love cls xxx love mly xxx love wls =============$@============= xxx love cls xxx love mly xxx love wls 当它们被双引号“”包含时,$*会将所有的参数作为一个整体,以“$1 $2 …$n”的形式输出所有参数;$@会将各个参数分开,以“$1” “$2”…“$n”的形式输出所有参数。 vim for4.sh

#!/bin/bash echo '=============$*=============' for i in "$*" #$*中的所有参数看成是一个整体,所以这个 for 循环只会循环一次 do echo "xxx love $i" done echo '=============$@=============' for j in "$@" #$@中的每个参数都看成是独立的,所以“$@”中有几个参数,就会循环几次 do echo "ban zhang love $j" done

chmod 777 for4.sh ./for4.sh cls mly wls 输出结果为:=============$*============= xxx love cls mly wls =============$@============= xxx love cls xxx love mly xxx love wls
4.4 while 循环 基本语法 while [ 条件判断式 ] do 程序 done 案例实操:从 1 加到 100 touch while.sh vim while.sh
#!/bin/bash sum=0 i=1 while [ $i -le 100 ] do sum=$[$sum+$i] i=$[$i+1] done echo $sum
chmod 777 while.sh ./while.sh 输出结果为:5050
五、shell函数使用函数来执行重复性的任务,是一个很好的方式来创建代码的重用。代码重用是现代面向对象编程的原则的重要组成部分。
5.1 创建函数:声明一个函数语法:function_name () {例子:#!/bin/bash# Define your function hereHello () {echo "Hello World"}# Invoke your functionHello
当你想执行上面的脚本,它会产生以下结果:Hello World
5.2 参数传递给函数你可以定义一个函数,它接受参数,而调用这些函数。将这些参数代表$1,$2,依此类推。例子:#!/bin/bash# Define your function hereHello () {echo "Hello World $1 $2"}# Invoke your functionHello Zhang lisi
这将产生以下结果:Hello World Zhang lisi5.3 从函数的返回值例子:#!/bin/bash# Define your function hereHello () {echo "Hello World $1 $2"return 1}# Invoke your functionHello Zhangsan lisir=$?echo "Return value is $r"
这将产生以下结果:Hello World Zhangsan lisiReturn value is 1
5.4 嵌套函数函数更有趣的功能之一是,他们可以调用本身以及调用其他函数。被称为递归函数调用自身的函数。例子:#!/bin/bash# Calling one function from anotherone () {echo "This is the first function"two}
two () {echo "This is the second function"}# Calling function one.one
这将产生以下结果:This is the first functionThis is the second function
页: [1]
查看完整版本: 关于shell脚本的学习