⌛️
文章目录
一、Shell 概述二、Shell 脚本的定义与执行2.1 Shell 脚本的定义2.2 Shell 脚本的执行 三、Shell 变量3.1 用户自定义变量3.2 环境变量3.3 位置变量3.4 预定义变量3.5 命令替换 四、Shell 输入与输出4.1 read 命令4.1 echo 命令 五、Shell 中的引号 ⭐️5.1 反引号5.2 单引号5.3 双引号 六、条件表达式6.1 文件状态操作符6.2 字符串操作符6.3 数字操作符6.4 逻辑操作符6.5 命令分隔符 七、判断语句7.1 条件语句7.2 分支语句 八、循环语句8.1 break、continue 和 exit 语句8.2 expr 命令8.3 for 语句8.4 while 语句8.5 until 语句 九、Shell 函数十、参考附录:Shell ☁️
上一篇文章链接:【Linux学习笔记③】——Linux的磁盘与加载【硬盘的物理结构 主引导记录 grub】.
上一篇文章链接:【Linux学习笔记⑤】——GNU C语言开发环境【GNU make、静态库】.
一、Shell 概述
首先,我们需清楚什么是脚本语言?
●脚本语言(Script languages)是为了缩短传统的编写-编译-链接-运行(edit-compile-link-run)过程而创建的计算机编程语言。几乎所有计算机系统的各个层次都有一种脚本语言。包括操作系统层,如计算机游戏,网络应用程序,文字处理文档,网络软件等。
一个脚本可以使得本来要用键盘进行的相互式操作自动化。一个 Shell 脚本主要由原本需要在命令行输入的命令组成,或在一个文本编辑器中,用户可以使用脚本来把一些常用的操作组合成一组序列。
●Shell语言:Shell语言 是指UNIX
操作系统的命令语言,同时又是该命令语言的解释程序的简称。Shell 作为语言来说,它既是终端上的用户与 UNIX 操作系统会话的语言,又可作为程序设计的语言,所以 Shell 是用户与系统之间的接口,而且是一种比较高级、易被用户理解和使用的程序设计语言,它为用户提供了使用方便、功能强、又容易扩充的程序设计环境。
● 所以,Shell 不仅是可解释用户输入的命令,同时,也是可解释执行基于命令的脚本语言。
常用的 Shell 版本有 Bourne Shell(简称 sh),C Shell(简称 csh)、Korn Shell(简称 ksh)和 Bourne Again Shell(简称 bash)。
二、Shell 脚本的定义与执行
2.1 Shell 脚本的定义
● Shell 脚本是由命令、Shell 变量和控制语句等语法元素构成的文本文件。Shell 会对脚本中的内容进行逐行分析,并加以解释和执行。下面给出一个简单的 Shell 脚本实例:
#!/bin/bash# script_test.shstr1="welcome to use Shell script!\n"str2="hello world!\n"echo $str1echo $str2
◆代码说明:
① 第一行以 “#!” 开始,用以说明选用何种 Shell 版本作为该脚本的解释器,这里选用 /bin/bash。
② 第二行以 “#” 开始,表示该行为注释,不参与执行,这里可以写一些脚本功能描述等。
③ 第三行定义了一个变量str1
。
④ 第五行执行 “显示变量str1
的值” 功能。
⑤\n
是换行字符。
●配置过程一:【注:需先在桌面右击,打开该终端】
◆代码说明:
① 命令touch
创建了一个.sh
脚本文件如图所示
② 命令vi
会打开该.sh
脚本文件,打开界面在下面
●配置过程二:
◆代码说明:
① 进入编辑页面如左上图所示,此时需要按i
键(insert),即从 “命令模式” 进入 “编辑模式”。
② 然后编辑右下图所示的代码。注:$
(引用符号)、echo
(输出命令)后面会学。
③ 接着按下ESC
(键盘最左上角)键,再从 “编辑模式” 进入 “命令模式”。
④ 最后先输入:
(英文冒号),再输入wq
(write and quit),写入并离开。
●最终结果图:
◆说明:最后,桌面上便有此脚本文件,右击它,然后点用其他应用程序打开
,便会进入文本编辑界面,我们也可以在这里面改代码。
2.2 Shell 脚本的执行
● 由于 Shell 脚本是文本文件,在编辑后默认不具有可执行的权限。因此为了和命令一样能运行,必须赋予执行权,具体操作如下:
$ chmod u+x script_test.sh # 给 demo.sh 增加可执行权$ ./script_test.sh # 直接运行
●运行结果:
● 没有给 Shell 脚本赋执行权的情况下,可以显式地指定 Shell 命令从而运行:
$ bash script_test.sh # 指定由 bash 解释执行
●Shell 脚本的解析过程如下:
◆图形说明:
① 在执行 Shell 脚本时,Shell 解析器会从脚本文件中从头至尾逐行取出每一条命令。
② 先对每一条命令进行语法检查,判断其合法性。
③ 在合法的情况下,会根据命令的类型分别进行处理。若为内部命令,则调用 Shell 解析器中相关的函数处理。
④ 若为外部命令,则 Shell 解析器会创建一个子进程,并在子进程中加载外部命令对应的可执行文件,并加以执行。
⑤ 无论何种类型的命令,在完成执行后,Shell 都会取下一条命令,重复上述过程直至脚本文件运行结束。
三、Shell 变量
S h e l l 变 量 的 分 类 = { 用 户 自 定 义 变 量 ( 局 部 变 量 ) 环 境 变 量 ( 全 局 变 量 ) 位 置 变 量 ( 局 部 变 量 ) 预 定 义 变 量 ( 局 部 变 量 ) Shell 变量的分类=\begin{cases}用户自定义变量(局部变量)\\环境变量(全局变量)\\位置变量(局部变量)\\ 预定义变量(局部变量)\end{cases} Shell变量的分类=⎩⎪⎪⎪⎨⎪⎪⎪⎧用户自定义变量(局部变量)环境变量(全局变量)位置变量(局部变量)预定义变量(局部变量)
●命名规则:变量名必须以字符或下划线开始,其余部分可为字母、数字或下划线。
3.1 用户自定义变量
■基本语法:变量名=变量值
▶功能:将 “变量值” 赋给变量 “变量名”
■相关语法一:$变量名
▶功能:引用该变量
■相关语法二:unset 变量名
▶功能:清除该变量的内容
■相关语法三:set
▶功能:显示当前已定义的所有变量的值
●样例:
$ var1=123# 给变量 var1 赋值123$ str1="welcome to bash" # 给变量赋值 "welcome to bash“$ unset str1 # 清除变量 str1 的值 $ set# 显示所有变量的值
●运行结果:
◆说明:因为str1
被unset
了,所以在 “变量列表” 里它的值为空(即 “_” ,只是str1
存储的空间内容清空了,但空间还在)
3.2 环境变量
● 环境变量又称全局变量,通常,由系统在启动时设置,环境变量一般用大写字母表示,通过env
命令可查看系统中定义的环境变量。用户自定义变量可通过命令export
输出为环境变量,环境变量的引用和用户自定义变量的引用方式相同。
■基本语法:export 用户自定义变量
▶功能:将 “用户自定义变量” 输出为环境变量
●样例:
$ x="hello i am global"# 定义变量 x, 并赋值 "hello welcome"$ bash # 创建子 bash$ echo $x# 变量 x 未定义$ exit # 退出子 bash$ export x # 将变量 x 输出为环境变量$ bash # 重新创建子 bash$ echo $x# 显示环境变量 x 的值 "hello welcome"$ x="Linux" # 定义同名局部变量 x, 并赋值为 "Linux"$ echo $x # 显示局部变量的值, 输出为 "Linux"$ exit # 退出子 bash$ echo $x # 显示环境变量x, 输出为 "hello welcome"
●运行结果:后期补充,这里知识点挺深的。
● Linux 系统中自带的环境变量较多,下面给出一些常用的环境变量:
●补充说明:
① 环境变量PATH
的值是由冒号分隔的目录路径名,当 Shell 在执行外部命令时,Shell 将按PATH
变量中给出的顺序搜索这些目录,执行与命令名匹配的第一个可执行文件。
② 环境变量PS1
,用于设置命令提示符,下面给出一些有特定含义的字符及其定义:
③ 环境变量PS2
在 Shell 接收用户输入命令的过程中,如果用户在输入行的末尾输入“\”
然后回车,或者当用户按回车键时 Shell 判断出用户输入的命令没有结束时,显示这个辅助提示符,缺省的辅助提示符是“>”
。
3.3 位置变量
● 位置变量由 Shell 内部定义,与传递参数的位置有关,下面给出位置参数的定义:
● 位置变量一般用在函数传参里,后面的“九、函数”中有相应样例。
3.4 预定义变量
● 预定义变量由 Shell 内部定义,具有特殊的含义,下面是一些 Shell 常用的预定义常量:
● 这个也是在后面的样例中有体现。
3.5 命令替换
● 当需要将命令的输出结果赋值给变量时,可使用命令替换,命令替换有两种语法形式。
■语法一:var=$(command)
■语法二:var=`command`
▶功能:将command
命令的运行结果赋给变量 var。【注意第二种写法是反引号
。即Tab
键上面那个键】
●样例:
# (1) 用户 "wly" 在名为 "wlyhostname" 的主机上输入以下命令$ echo "User $(whoami) is on $(hostname)"# 注:(whoami——>问我是谁的意思)# (2) 显示当天的日期和时间$ echo "Today is" `date`
●运行结果:
四、Shell 输入与输出
● 除直接给变量赋值外,用户还可以利用read
命令通过键盘给变量赋值。这样便实现了在运行过程中 Shell 脚本与用户之间的交互。同时,利用echo
命令可将各种信息输出到终端显示器。
4.1 read 命令
■语法:read [选项] 变量名列表
▶功能:从键盘上读取变量的值
●常用的一些选项如下:
●样例:
$ read -n 1 -p "Please input a character:" answer# 从键盘读取一个字符$ read var1 var2# 输入变量 var1 和 var2
●运行结果:
4.1 echo 命令
■语法:echo [选项] 字符串
▶功能:显示字符串或变量的值
●常用的一些选项如下:
● 下面给出echo
命令支持的一些转义符:
# 2行3列显示$ echo -e "a\tb\tc\nd\te\tf" # 运行结果如下:abcdef
五、Shell 中的引号 ⭐️
● 一些字符在 Shell 中具有特定的含义,这些字符称为元字符。不同的引号(反引号、单引号、双引号)对元字符的处理方式不同。
5.1 反引号
●反引号的作用:将一对反引号之间的命令用该命令的执行结果来代替,实现命令替换。
"举例如下"$ var1=`ls –l` # 将命令 'ls -l' 的执行结果赋给变量 var1$ echo `pwd` # 屏幕将会显示当前路径
5.2 单引号
● 在一对单引号中的所有字符(包括元字符),将失去特殊含义,都变成字符串形式。
"实例分析:"(1) 显示当前目录下的所有文件$ echo *# 将元字符 '*' 作为通配符处理(2) 显示字符'*' $ echo '*'# 单引号使元字符失去了特定的含义(3) 不进行变量替换$ text='* means all files' # 将单引号内的字符串赋给变量text$ echo '$text'# 显示'$text',不进行变量替换$ echo $text # 变量替换,并处理替换后的字符串命令 echo $text 首先显示当前目录下的所有文件,然后显示 'means all files', 其功能与下列命令相同。$ echo * means all files
5.3 双引号
● 在一对双引号中的字符(包括元字符),除了美元符$
、反引号`
和反斜杠\
外,其余均保留原来字符的含义。
●双引号的特点:
① 关闭通配符扩展对双引号中的元字符不作处理,保留其原有的含义。
② 支持变量替换将双引号中引用的变量用变量值进行替换。
③ 支持命令替换将双引号内一对反引号中的命令替换为该命令运行的结果
"实例分析:"(1) 假设用户为超级用户 root, 下面给出双引号对 $ 和 ` 和 \ 的处理方式。$ dlist='whoami'$ echo "* $dlist end" # 运行结果为: * whoami end, 元字符 '*' 不作特殊处理,将变量 $dlist 替换为变量的值 'whoami'。$ echo "`$dlist`" "# 先变量替换, 即将 $dist 替换为 whoami(问我是谁的意思), 然后进行命令替换# 运行结果为: root(2) 不加双引号与加双引号的比较$ x=*$ echo $x # 显示当前目录下的所有文件$ echo "$x"# 仅显示变量 x 的值'*'(3) 双引号对回车换行的处理$ text="I am a > sentence"$ echo $text# 运行结果为:I am a sentence$ echo "$text"# 运行结果为:I am asentence
六、条件表达式
● 条件表达式用于判断条件是否满足的逻辑表达式。条件为真,返回 0,否则,返回 1。它是选择和循环语句的基础。
■语法一:test 条件表达式
■语法二:[条件表达式]
▶功能:测试 “条件表达式” 是否为真,若真则返回 0,否则返回 1。
6.1 文件状态操作符
● 文件状态测试的目的是测试文件是否具有某种属性,例如文件是否可执行,文件是否是普通文件等。文件状态测试操作符的常用定义如下:
●样例如下:
◆说明:$?
表示在上一条命令执行后返回的状态,0
表示为真
(或者成功执行
),其他值为假
。
6.2 字符串操作符
● 字符串操作符用于判断字符串的性质以及字符串之间的关系。
●样例如下:
◆说明:$?
表示在上一条命令执行后返回的状态,0
表示为真
(或者成功执行
),其他值为假
。
6.3 数字操作符
● 数字操作符操作的对象是数组,用于比较两个数值的大小关系。
●样例如下:
◆说明:$?
表示在上一条命令执行后返回的状态,0
表示为真
(或者成功执行
),其他值为假
。
6.4 逻辑操作符
● 若操作对象是逻辑表达式,则使用逻辑操作符,下面是常用逻辑操作符的定义。
●样例如下:
6.5 命令分隔符
● 每个命令在运行后,都会返回一个值。一般情况下,成功则返回 0,成功则返回非 0。常用的分隔符如下:
●样例如下:
(1)测试 number 的值是否在 1 ~ 100 之间:$ [ "$number" -gt 1 ] && [ "$number" -lt 100 ](2)检测文件 file 是否为空, 如果不为空就显示其内容:$ test -s $file && cat $file
七、判断语句
7.1 条件语句
● 条件语句将根据条件表达式的值决定下一步执行何种操作。
■语法一:
if [ 条件表达式 ]then命令序列1else命令序列2fi
▶功能:当 “条件表达式” 的测试值为真时,执行 “命令序列1” ,否则,执行 “命令序列2” 。命令序列中的命令可以是一个或者多个。
■语法二:
if [ 条件表达式 ];then命令序列fi
▶功能:当 “条件表达式” 的测试值为真时,执行 “命令序列”,否则,执行条件语句后面的命令。条件表达式与 then 之间的分号 “;” 起命令分隔符的作用。
■语法三:
if test 条件表达式1then命令序列1elif [条件表达式2]then命令序列2 else命令序列3fi
▶功能:这是包含二层嵌套的条件语句,当 “条件表达式1” 为真时,执行 “命令序列1”,否则,在 “条件表达式2” 为真的情况下,执行 “命令序列2”,否则,执行 “命令序列3” ,“命令序列3” 属于第 2 个条件语句的一部分。
●样例一:判断当前目录下是否存在某文件
#!/bin/bash# script_test.shecho "Enter a file name:"read fileif [ -f $file ]thenecho "File $file exists."fi
●运行结果:
●样例二:判断当前用户是否和输入的用户名一致
#!/bin/sh# script_test.shecho -n "Enter your login name:"read nameif [ "$name" = "$USER" ];thenecho "Hello, $name. How are you today ?"elseecho "You are not $USER, so who are you ?"fi
●运行结果:
●样例三:比较两个数的大小
#!/bin/sh# script_test.shecho "Enter the first integer:"read firstecho "Enter the second integer:"read secondif [ "$first" -gt "$second" ]then echo "$first is greater than $second"elif [ "$first" -lt "$second" ]then echo "$first is less than $second" elseecho "$first is equal to $second" fi
●运行结果:
●样例四:在文本文件中找查字符串
#!/bin/sh# script_test.shecho "Enter the file name:"read myfileif grep "hello" $myfilethen echo "\"hello\" occurs in myfile"elseechoecho "\"hello\" dose not occur in myfile"fi
●运行结果:
7.2 分支语句
● 如果某个变量或表达式存在多种取值,不同的取值决定不同的行为动作,如果取值较多时,使用if
语句可能比较复杂,这时即可采用分支语句。
■语法:
case 变量 in值1) 命令序列1;;值2) 命令序列2;;......值n) 命令序列n;;esac
▶功能:当 “变量” 的值为 “值1” 时,执行 “命令序列1”,当 “变量” 的值为 “值2” 时,执行 “命令序列2”,依此类推,需注意的是:在每个命令序列后面,需要用 “;;” 作为结束标记。
● 在case
语句中,有时会出现一些特殊的字符,用于模式匹配:
●样例:判断当前时间属于上午、下午或晚上
#!/bin/bash# script_test.shhour=`date "+%H"`# spaceKey can't forgetcase $hour in0[1-9] | 1[01] ) # '0[1-9]' represents '01,02,03,...,09'echo "Current time is $hour."echo "Good morining !!" ;;1[2-7] ) # '1[2-7]' represents '12,13,...,17'echo "Current time is $hour."echo "Good afternoon !!" ;;* ) echo "Current time is $hour."echo "Good evening !! " ;;esac
●运行结果:
八、循环语句
● 循环语句就是不断执行循环体内的命令,直到循环条件满足或不满足为止。在 Shell 中,循环语句包括 for 语句、while 语句和 until 语句。
8.1 break、continue 和 exit 语句
■break语法:
break [n]
▶功能:表示从循环中跳出,n
表示是跳出几层循环,默认是1
。
■continue语法:
continue [n]
▶功能:表示跳过循环体中在它之后的语句,回到循环开头,进行下一次循环。
■exit语法:
exit [n]
▶功能:退出运行脚本,n
为运行脚本的返回值。
8.2 expr 命令
■语法:
expr 算术表达式
▶功能:计算算术表达式的值,在每个算术运算符的两边必需用空格符分割。
●样例如下:
$ expr 1 + 2# 结果为 3 $ expr 2 \* 3# 结果为 6$ count=4;$ count=`expr $count + 1`# 结果为 5
8.3 for 语句
■语法:
for 变量名 in 参数列表do命令1命令2...done
▶功能:将 “参数列表” 中的元素依次赋值给 “变量名”,在每次赋值后执行 “命令1”、“命令2”、…,直到执行到 done 结束。
●样例:求若干数中的最小值
#!/bin/bash# script_test.shsmallest=10000for i in 12 5 18 58 -3 80doif test $i -lt $smallestthensmallest=$ifidoneecho " The smallest number is: $smallest"
●运行结果:
8.4 while 语句
■语法:
while [ 条件表达式 ]do命令1命令2...done
▶功能:循环执行 “命令1”、“命令2”、…,直至 “条件表达式” 中的值为假。
●样例一:计算 1 到 100的和
#!/bin/bash# script4_test.shi=1sum=0while [ $i -le 100 ] dosum=`expr $sum + $i`i=`expr $i + 1`doneecho The sum is $sum
●运行结果:
●样例二:显示 2~100 之间的所有素数
#!/bin/bash# script_test.shi=2while [ $i -le 100 ]doj=2flag=1# flag 为 1 表示 i 是素数while [ $j -le `expr $i / 2` ]doif [ `expr $i % $j` -eq 0 ]then flag=0;breakfij=`expr $j + 1`doneif [ $flag -eq 1 ]then echo "${i} is a prime"fii=`expr $i + 1`done
●运行结果:
8.5 until 语句
■语法:
until 条件表达式do命令1命令2...done
▶功能:循环执行 “命令1”、“命令2”、…,直至 “条件表达式” 的值为真。
●样例:输入文件名至文件 myfile.txt,直至输入 no
#!/bin/bash# script_test.shans=yesuntil [ "$ans" = no ]doecho Enter a characterread characterecho $name >> myfile.txtecho "Continue?"echo Enter yes or noread ansdone
●运行结果:
九、Shell 函数
● 为了使规模较大的程序容易实现和维护,一般将程序按功能分解为若干函数,每个函数完成一个特定的功能,然后通过函数调用实现程序的各个功能。
■函数定义语法:
函数名( ){命令1命令2...return }
■函数调用语法:
函数名 参数列表
●注意事项:
① 调用前,必须先进行定义。
② 用 Shell 定义的位置变量接收参数传递,例如,$0
、$1
和$#
等。
③ 返回值取自函数中return
语句或函数中最后一条命令的返回状态,可通过$?
获得。
④ 函数中定义了与全局变量同名的局部变量,则在函数中,同名局部变量生效。
⑤ 可·使用local
声明的局部变量,其作用仅限于函数本身。
●样例:运行函数比较两个数的大小关系
#!/bin/bash# script_test.shcompare(){if [ $p1 -eq $p2 ]then return 0elif [ $p1 -gt $p2 ]then return 1elsereturn 2fi}echo "Compare test."read -p "Please input your parameter1: " p1read -p "Please input your parameter2: " p2compare $p1 $p2case $? in0)echo "$p1 = $p2";;1)echo "$p1 > $p2";;2)echo "$p1 < $p2";;esac
●运行结果:
十、参考附录:
[1]《GNU/Linux编程》📚
人民邮电出版社
[2]linux Vi操作和使用方法详解
链接: /xie_xiansheng/article/details/78413306.
[3]Linux之Shell脚本的条件判断和函数
链接: /fy_java1995/article/details/101095961.
上一篇文章链接:【Linux学习笔记③】——Linux的磁盘与加载【硬盘的物理结构 主引导记录 grub】.
上一篇文章链接:【Linux学习笔记⑤】——GNU C语言开发环境【GNU make、静态库】.
⭐️ ⭐️
【Linux学习笔记④】——Shell程序设计【变量 输入与输出 条件表达式 判断语句 循环语句 Shell函数】