2.Shell 编程(超牛主讲)

教程 阿布都的都 ⋅ 于 2023-01-06 15:01:44 ⋅ 最后回复由 wtf2012 2023-09-26 09:37:46 ⋅ 1072 阅读

Linux Shell编程

1 Shell简介

1.1 什么是shell

shell是用C语言编写的程序,它是用户使用 Linux 的桥梁。Shell既是一种命令语言,又是一种程序设计语言。简单来说Shell 是指一种应用程序,这个应用程序提供了一个界面,用户通过这个界面访问操作系统内核的服务。也可以这样认为,linux中的shell就是linux内核的一个外层保护工具,并负责完成用户与内核之间的交互。

file

1.2 shell脚本

shell脚本就是一种专门使用shell编写的脚本程序,它虽然没有C++、Java、Python等一系列高级语言功能强大,但是在服务器运维领域以及嵌入式开发领域,shell脚本具有举足轻重的地位。

shell脚本编程如同其他编程语言的一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以运行了,而linux下的shell种类众多,常用的有:

  • Bourne Shell(/usr/bin/sh或/bin/sh)
  • Bourne Again Shell(/bin/bash)
  • C Shell(/usr/bin/csh)
  • K Shell(/usr/bin/ksh)
  • Shell for Root(/sbin/sh)
  • … …

在诸多linux发行版系统中,最常用的就是Bash,就是Bourne Again Shell,因为它能够提供环境变量以配置用户shell环境,支持历史记录、内置算数功能、支持通配符表达式等高效性能,将linux常用命令进行简化,被广泛应用于Debian系列的linux发行版中。

1.3 运行shell脚本

运行shell脚本的方法有两种:

  • 作为可执行程序运行
  • 作为解释器参数运行

1.4 入门程序

shell编写的基本步骤:

  • 建立shell文件
  • 赋予shell文件可执行程序权限(使用chmod命令修改权限)
  • 执行shell文件(直接运行赋予权限后的二进制文件)

① 创建hello.sh文件,使用vim编辑内容如下:

shell脚本名称一般采用英文命名,后缀为.sh,不能使用特殊符号和空格。

shell编程首行需要 #!/bin/bash 开头。

#!/bin/bash
echo "Hello World"

② 赋予可执行权限

chmod +x hello.sh   # 赋予可执行权限

③ 执行

# 作为可执行程序运行
./hello.sh

# 作为解释器参数运行
sh ./hello.sh

1.5 shell中的注释

  • 单行注释:和python注释相同,以#号开头作为单行注释
#!/bin/bash
# 这是我的第一个shell脚本
echo "Hello World"
  • 多行注释:
:<<EOF  # EOF也可以换成其他符号
注释内容...
注释内容...
注释内容...
EOF

2 Shell变量

Shell编程中变量分为三种,分别是系统变量、环境变量和用户变量。Shell变量名在定义时,首个字符必须为字母(a-z,A-Z),不能以数字开头,中间不能有空格,可以使用下划线(_),不能使用(-),也不能使用标点符号等。

2.1 系统变量

Shell的系统变量,主要是在对参数判断和命令返回值判断时使用,系统变量详解如下:

$0      当前脚本的名称;
$n      当前脚本的第n个参数,n=1,2,…9;
$*      当前脚本的所有参数(不包括程序本身);
$#      当前脚本的参数个数(不包括程序本身);
$?      命令或程序执行完后的状态,返回0表示执行成功;
$$      程序本身的PID号。

2.2 环境变量

环境变量,主要是在程序运行时需要设置。其中又分为:

  • 对所有用户生效的环境变量(系统级变量) /ect/profile

  • 对特定用户生效的环境变量 ~/.bashrc 或者 ~/.bash_profile

  • 临时有效的环境变量 脚本或命令行中使用export
# 常用的环境变量如下:
PATH        命令所示路径,以冒号为分割;
HOME        打印用户家目录;
SHELL       显示当前Shell类型;
USER        打印当前用户名;
ID          打印当前用户id信息;
PWD         显示当前所在路径;
TERM        打印当前终端类型;
HOSTNAME    显示当前主机名;
PS1         定义主机命令提示符的;
HISTSIZE    历史命令大小,可通过 HISTTIMEFORMAT 变量设置命令执行时间;
RANDOM      随机生成一个 0 至 32767 的整数;
HOSTNAME    主机名

2.3 局部变量

局部变量又称为用户变量,主要用在Shell脚本内部或者临时局部使用。

num = 10;

shell编程中,定义变量是直接定义的,没有明确的数据类型,shell允许用户建立变量存储数据,但是将赋给变量的值都解释为一串字符

shell中,英文符号"$"用于取变量值。

#!/bin/bash
name="Jack"
echo $name      # 输出Jack
num=10
echo $num       # 输出10
str=abc
echo $str       # 输出abc

注意:

① shell编程的变量名和等号之间不能有空格;变量名的命名和其他语言一样,需要遵循一定的规则,规则如下:

  • 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头
  • 中间不能有空格,可以使用下划线(_)
  • 不能使用标点符号
  • 不能使用bash里的关键字(可用help命令查看保留关键字)

② 如果使用系统命令,需要加一对反单引号(Esc键下方)

#!/bin/bash
# 如果使用系统命令,需要加一对反单引号
date=`date`
echo $date

③ 对于较长的变量名,建议加上一对大括号,帮助解释器识别变量的边界,也有利于阅读

#!/bin/bash
# 对于较长的变量名,建议加上一对大括号,帮助解释器识别变量的边界,也有利于阅读
# 获取变量时$符号前面和变量名称后面必须有一个空格,以区分变量和其他字符串
# 但加上{} 后,即使没有空格也能识别
name="Jack"
echo "my name is $name"
echo "my name is ${name}"
echo "my name is$nameaaa"   ## 无法识别变量
echo "my name is $nameaaa"  ## 无法识别变量
echo "my name is${name}aaa"

④ shell中的变量,默认为可读可写类型,如果想要其只可读,可以使用readonly命令将其声明为只读类型变量

#!/bin/bash
Url="https://www.baidu.com"
readonly Url
Url="https://www.google.com"    # 此处报错,只读变量

⑤ 如果想要删除变量,使用unset命令解除命令赋值,但是unset不能删除只读变量。

#!/bin/sh
name="Jack"
Url="https://www.baidu.com"
readonly Url    # 设置可读变量
unset name      # 可以被删除
unset Url       # 不可被删除
echo $name      # 不被打印出
echo $Url       # 打印出

3 Shell中的字符串

3.1 字符串类型

在shell中字符串是shell编程中最常用最有用的数据类型,字符串可以用单引号,也可以用双引号,也可以不用引号。

#!/bin/bash
str1='hello'
echo $str1  ## 输出hello

str2="bigdata"
echo $str2  ## 输出bigdata

str3=shell
echo $str3 ## 输出shell

# 以下是使用echo命令直接输出
echo 'hello'
echo "bigdata"
echo shell

注意,使用单引号的问题:

  • 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的
  • 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
#!/bin/bash
str1='Jack'
str2='my name is ${str1}'
echo $str2  ## 输出my name is ${str1}

# 不能出现单个单引号
str3='this is \'test'
echo $str3  ## 此处报错

所以,建议使用双引号,在双引号中,可以使用变量,也可以使用转义字符。

#!/bin/bash
name="Jack"
str="my name is ${name}"
echo $str       ## 输出my name is Jack

s="this is \"test\""
echo $s         ## 输出this is "test"

3.2 字符串操作

获取字符串长度:在获取变量值时,使用#符号可以获取字符串长度

# ${#var},获取变量长度
string="abcd"
echo ${#string} # 输出 4

提取子字符串:使用字符串的截取命令,用于提取部分字符串

# ${var:pos} ,获取变量var从指定pos位置开始到结束的字符串
string="hello world"
echo ${string:6}        ## 从索引为6的字符开始截取到末尾
world

# ${var:pos:length},获取变量var从指定pos位置开始提取长度为length的字符串
string="thisisatest"
echo ${string:2:6}      ## 表示从索引为2(第3个)的字符开始截取,截取6个字符
isisat

删除匹配的子串

# ${var#substring},表示从变量var的起始位置,删除最短匹配$substring的字符串
str="/home/shell/script.sh"
echo ${str#*/}      ## 删除匹配 */
home/shell/script.sh

# ${var##substring},表示从变量var的起始位置,删除最长匹配$substring的字符串
str="/home/shell/script.sh"
echo ${str##*/}     ## 删除匹配 */
script.sh

# ${var%substring},表示从变量var的结束位置开始删除最短匹配$substring的字符串
str="/home/shell/script.sh"
echo ${str%/*}      ## 删除匹配 /*
/home/shell

# ${var%%substring},表示从变量var的结束位置开始删除最长匹配$substring的字符串
str="root/home/shell/script.sh"
echo ${str%%/*}
root

替换匹配的子串

# ${var/substring/replace_str},表示使用$replace_str来代替从变量var开始位置第一个匹配到的$substring
str="I like shell shell is good"
echo ${str/shell/java}
I like java shell is good

# ${var//substring/replacement},表示使用$replacement代替所有匹配的$substring
str="I like shell shell is good"
echo ${str//shell/java}
I like java java is good

# ${var/#substring/replace_str},表示如果变量var的前缀匹配$substring, 那么就用$replace_str来代替匹配到的$substring。必须是第一个字符开始就满足匹配条件。
var="oracle/oracle/script.sh"
echo ${var/#oracle/opt}
opt/oracle/script.sh

# ${var/%substring/replace_str} ,表示如果$string的后缀匹配$substring, 那么就用$replace_str来代替匹配到的$substring。必须是结尾部分满足匹配条件。
var="/oracle/oracle/script.sh"
echo ${var/%sh/txt}
/oracle/oracle/script.txt

说明:(1)substring可以是正则表达式;(2)${string#substring}与${string%substring}是从开始还是结尾开始匹配总是容易混淆,可以这么理解,注释符#总是在前面,#号是从前面开始匹配的。

4 Shell数组

在bash下,仅仅支持一维数组,并且没有限定数组的大小,不支持多维数组。数组元素的下标由 0 开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于 0。

4.1 定义数组

在 Shell 中,用括号()来定义表示数组,数组中元素用"空格"符号分割开。定义数组的一般形式为:

# 一般定义
array_name=(value1 value2 value3 value4)

# 多级定义
array_test=(
value1 
value2 
value3 
value4
)

# 还可以单独定义数组的各个元素
array_text[0]=value0
array_text[1]=value1
array_text[3]=value3
... 
...

4.2 数组操作

访问数组中的元素

${数组名[下标]}

示例:

arr=("tom" "jerry" "jack" "john")
value1=${arr[0]}
echo $value1        # 获取第1个元素

echo ${arr[@]}      # 读取所有
# 或者
echo ${arr[*]}      # 读取所有

# 取得数组元素的个数
length=${#array_name[@]}    # 从头到尾取
# 或者
length=${#array_name[*]}    # 取所有

# @和*区别:“${数组变量[*]}”:加上双引号,bash会当成是一串字符串处理
# ${数组变量[*]}:不加上双引号,bash会当成是数组处理

# ${数组变量[@]:加不加双引号bash都是当成数组处理

5 Shell传递参数

在执行 Shell 脚本时,向脚本传递参数,脚本内获取参数的格式为:$nn 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推。

编写脚本,保存为test.sh

echo "传递参数实例!";
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";

执行脚本

chmod +x test.sh
./test.sh 1 2 3

输出:

传递参数实例!
执行的文件名:./test.sh
第一个参数为:1
第二个参数为:2
第三个参数为:3

使用shell传递参数的时候,常常需要用到以下的几个字符来处理参数:

参数处理 说明
$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数。 以"$1 $2 … $n"的形式输出所有参数。
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
$@ 与∗相同,但是使用时加引号,并在引号中返回每个参数。以"$1" "$2" …"$n" 的形式输出所有参数。
$- 显示Shell使用的当前选项,与set命令功能相同。
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。

6 Shell 运算符

6.1 运算符种类

与其他编程语言相同的是,shell同样支持多种运算符:

  • 算数运算符
  • 关系运算符
  • 布尔运算符
  • 字符串运算符
  • 文件测试运算符

shell想要使用这些运算符,需要结合其他命令和工具来使用(因为shell中不支持简单的数学运算),如使用算符运算符就需要搭配的常用的工具有两种

  • awk
  • expr(使用频繁)

运算规则注意点:

  • 表达式和运算符之间必须要有空格,例如 3+2 是不对的,必须写成 3 + 2

  • 完整的表达式要被 两个" ` "包含(在 Esc 键下边那个键)

6.2 算术运算符

假定变量a的值为10,变量b的值为20

运算符 说明 举例
+ 加法 expr $a + $b 结果为 30。
- 减法 expr $a - $b 结果为 -10。
* 乘法 expr $a \* $b 结果为 200。
/ 除法 expr $b / $a 结果为 2。
% 取余 expr $b % $a 结果为 0。
= 赋值 a=$b 将把变量 b 的值赋给 a。
== 相等。用于比较两个数字,相同则返回 true。 [ $a == $b ] 返回 false。
!= 不相等。用于比较两个数字,不相同则返回 true。 [ $a != $b ] 返回 true。

注意:在windows系统中乘号(*)前边必须加反斜杠转义才能实现乘法运算。

示例:

#!/bin/bash
a=10
b=20
val=`expr ${a} + ${b}`
echo "a + b : ${val}"
val=`expr ${a} - ${b}`
echo "a - b : ${val}"
val=`expr ${a} \* ${b}`
echo "a * b : ${val}"
val=`expr ${a} / ${b}`
echo "a / b : ${val}"
val=`expr ${a} % ${b}`
echo "a % b : ${val}"

6.3 关系运算符

shell中的关系运算符和其他编程语言不同,shell中使用特殊的字符表示关系运算符,并且只支持数字,不支持字符串,除非字符串是数字,下表为常用关系运算符,同样指定a为10,b为20。

运算符 说明 举例
-eq 检测两个数是否相等,相等返回 true。 [ $a -eq $b ] 返回 false。
-ne 检测两个数是否不相等,不相等返回 true。 [ $a -ne $b ] 返回 true。
-gt 检测左边的数是否大于右边的,如果是,则返回 true。 [ $a -gt $b ] 返回 false。
-lt 检测左边的数是否小于右边的,如果是,则返回 true。 [ $a -lt $b ] 返回 true。
-ge 检测左边的数是否大于等于右边的,如果是,则返回 true。 [ $a -ge $b ] 返回 false。
-le 检测左边的数是否小于等于右边的,如果是,则返回 true。 [ $a -le $b ] 返回 true。

示例:

#!/bin/bash
a=10
b=20

if [ $a -eq $b ]
then
   echo "$a -eq $b : a 等于 b"
else
   echo "$a -eq $b: a 不等于 b"
fi

执行结果:

10 -eq 20: a 不等于 b

注意:运算符和数之间必须要用空格隔开

6.4 布尔运算符

假定变量 a 为 10,变量 b 为 20:

运算符 说明 举例
! 非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。
-o 或运算,有一个表达式为 true 则返回 true。 [ $a -lt 20 -o $b -gt 100 ] 返回 true。
-a 与运算,两个表达式都为 true 才返回 true。 [ $a -lt 20 -a $b -gt 100 ] 返回 false。

示例:

#!/bin/bash
a=10
b=20
if [ $a -lt 100 -a $b -gt 15 ]
then
   echo "$a 小于 100 且 $b 大于 15 : 返回 true"
else
   echo "$a 小于 100 且 $b 大于 15 : 返回 false"
fi

输出

10 小于 100 且 20 大于 15 : 返回 true

6.5 逻辑运算符

假定变量 a 为 10,变量 b 为 20:

运算符 说明 举例
&& 逻辑的 AND [[ $a -lt 100 && $b -gt 100 ]] 返回 false
|| 逻辑的 OR [[ $a -lt 100 || $b -gt 100 ]] 返回 true

示例:

#!/bin/bash
a=10
b=20

if [[ $a -lt 100 && $b -gt 100 ]]
then
   echo "返回 true"
else
   echo "返回 false"
fi

if [[ $a -lt 100 || $b -gt 100 ]]
then
   echo "返回 true"
else
   echo "返回 false"
fi

执行结果:

返回 false
返回 true

6.6 字符串运算符

shell中常用的字符串运算符如下表。假定变量 a 为 “abc”,变量 b 为 “efg”

运算符 说明 举例
= 检测两个字符串是否相等,相等返回 true。 [ $a = $b ] 返回 false。
!= 检测两个字符串是否相等,不相等返回 true。 [ $a != $b ] 返回 true。
-z 检测字符串长度是否为0,为0返回 true。 [ -z $a ] 返回 false。
-n 检测字符串长度是否不为 0,不为 0 返回 true。 [ -n “$a” ] 返回 true。
$ 检测字符串是否为空,不为空返回 true。 [ $a ] 返回 true。

示例:

#!/bin/bash
a="abc"
b="efg"

if [ $a = $b ]
then
   echo "$a = $b : a 等于 b"
else
   echo "$a = $b: a 不等于 b"
fi
if [ $a != $b ]
then
   echo "$a != $b : a 不等于 b"
else
   echo "$a != $b: a 等于 b"
fi
if [ -z $a ]
then
   echo "-z $a : 字符串长度为 0"
else
   echo "-z $a : 字符串长度不为 0"
fi
if [ -n "$a" ]
then
   echo "-n $a : 字符串长度不为 0"
else
   echo "-n $a : 字符串长度为 0"
fi
if [ $a ]
then
   echo "$a : 字符串不为空"
else
   echo "$a : 字符串为空"
fi

执行结果:

abc = efg: a 不等于 b
abc != efg : a 不等于 b
-z abc : 字符串长度不为 0
-n abc : 字符串长度不为 0
abc : 字符串不为空

6.7 文件检测运算符

文件测试运算符用于检测 Unix 文件的各种属性。

操作符 说明 举例
-b file 检测文件是否是块设备文件,如果是,则返回 true。 [ -b $file ] 返回 false。
-c file 检测文件是否是字符设备文件,如果是,则返回 true。 [ -c $file ] 返回 false。
-d file 检测文件是否是目录,如果是,则返回 true。 [ -d $file ] 返回 false。
-f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 [ -f $file ] 返回 true。
-g file 检测文件是否设置了 SGID 位,如果是,则返回 true。 [ -g $file ] 返回 false。
-k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 [ -k $file ] 返回 false。
-p file 检测文件是否是有名管道,如果是,则返回 true。 [ -p $file ] 返回 false。
-u file 检测文件是否设置了 SUID 位,如果是,则返回 true。 [ -u $file ] 返回 false。
-r file 检测文件是否可读,如果是,则返回 true。 [ -r $file ] 返回 true。
-w file 检测文件是否可写,如果是,则返回 true。 [ -w $file ] 返回 true。
-x file 检测文件是否可执行,如果是,则返回 true。 [ -x $file ] 返回 true。
-s file 检测文件是否为空(文件大小是否大于0),不为空返回 true。 [ -s $file ] 返回 true。
-e file 检测文件(包括目录)是否存在,如果是,则返回 true。 [ -e $file ] 返回 true。

示例:

变量 file 表示文件 /var/www/runoob/test.sh,它的大小为 100 字节,具有 rwx 权限。下面的代码,将检测该文件的各种属性:

#!/bin/bash

file="/var/www/runoob/test.sh"
if [ -r $file ]
then
   echo "文件可读"
else
   echo "文件不可读"
fi
if [ -w $file ]
then
   echo "文件可写"
else
   echo "文件不可写"
fi
if [ -x $file ]
then
   echo "文件可执行"
else
   echo "文件不可执行"
fi
if [ -f $file ]
then
   echo "文件为普通文件"
else
   echo "文件为特殊文件"
fi
if [ -d $file ]
then
   echo "文件是个目录"
else
   echo "文件不是个目录"
fi
if [ -s $file ]
then
   echo "文件不为空"
else
   echo "文件为空"
fi
if [ -e $file ]
then
   echo "文件存在"
else
   echo "文件不存在"
fi

执行结果:

文件可读
文件可写
文件可执行
文件为普通文件
文件不是个目录
文件不为空
文件存在

7 Shell编程中的命令

7.1 echo命令

echo命令在shell中用于字符串的输出,调用的格式:

echo string

示例:

显示转义字符

echo "\this is a test\"

显示变量

name="jack"
echo "you name is ${name}"

显示换行

echo -e "Right!\n " # -e 表示开启转义
echo "this is other line"

显示结果定向重定向至文件

echo "this is a test" >> testfile

显示command命令执行结果

echo `date`

7.2 printf命令

与echo命令打印字符串不同的是,printf不会自动添加换行符号,可以手动添加。

示例:

#!/bin/bash
# 手动添加换行
printf "hello world\n"

# 打印中接收变量
#!/bin/bash
age=10
name=zhangsan
printf "%s的年龄是:%d岁\n" $name $age

# 格式化输出  例如:
#!/bin/bash
username=($(head -10 /etc/passwd | awk -F: '{print $1}'))
usernum=${#username[@]}
uid=($(head -10 /etc/passwd | awk -F: '{print $3}'))

for ((i = 0; i < ${usernum}; i++));
do
printf "%-10s%d\n" ${username[$i]} ${uid[$i]}
done

7.3 test命令

shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试。

数值测试命令表

参数 说明
-eq 等于则为真
-ne 不等于则为真
-gt 大于则为真
-ge 大于等于则为真
-lt 小于则为真
-le 小于等于则为真

示例:

#!/bin/bash
num1=100
num2=100
if test $[num1] -eq $[num2]
then
    echo '两个数相等!'
else
    echo '两个数不相等!'
fi

字符串测试表

参数 说明
= 等于则为真
!= 不相等则为真
-z 字符串 字符串的长度为零则为真
-n 字符串 字符串的长度不为零则为真

示例:

# !/bin/bas
num1="name"
num2="function"
if test $num1 = $num2
then
    echo '两个字符串相等!'
else
    echo '两个字符串不相等!'
fi

文件测试表

参数 说明
-e 文件名 如果文件存在则为真
-r 文件名 如果文件存在且可读则为真
-w 文件名 如果文件存在且可写则为真
-x 文件名 如果文件存在且可执行则为真
-s 文件名 如果文件存在且至少有一个字符则为真
-d 文件名 如果文件存在且为目录则为真
-f 文件名 如果文件存在且为普通文件则为真
-c 文件名 如果文件存在且为字符型特殊文件则为真
-b 文件名 如果文件存在且为块特殊文件则为真

示例:

# !/bin/bash
if test -e ./bash
then
    echo '文件已存在!'
else
    echo '文件不存在!'
fi

8 shell流程控制

shell作为一种脚本语言,也有着自己的流程控制,而shell中的流程控制主要由条件、循环组成。

8.1 if else条件

语法:

if

# if语句第一种格式
if condition
then
    command1 
    command2
    ...
    commandN 
fi
# 写成一行使用分号将语句分开 

# if else 语法格式:
if condition
then
    command1 
    command2
    ...
    commandN
else
    command
fi

# if else-if else 语法格式:
if condition1
then
    command1
elif condition2 
then 
    command2
else
    commandN
fi

写成一行示例:

# 判断进程中包含ssh信息的进程的数量 是否 > 1
if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi

示例:

创建脚本文件 iftest.sh

#!/bin/bash
num=$1
if [[ $num -ge 90 && $num -le 100 ]]
then
echo "${num} 成绩优秀"
elif [[ $num -ge 80 && $num -le 89 ]]
then
echo "${num} 成绩良好"
elif [[ $num -ge 60 && $num -le 79 ]]
then
echo "${num} 成绩及格"
else
echo "${num} 成绩不合格"
fi

执行结果:

./iftest.sh 100
100 成绩优秀

8.2 case条件

shell中case语句为多功能选择语句,与其他语言相通的是,可以用case语句匹配一个值与一个模式,如果匹配成功,执行相匹配的命令。case语句调用格式如下:

case 值 in
模式1)
    command1
    command2
    ...
    commandN
    ;;
模式2)
    command1
    command2
    ...
    commandN
    ;;
esac

需要注意的点:

  • 取值后面需要加上in
  • 每一模式必须以右括号结束
  • 每个模式结束后使用;;符号结尾
  • 如果没有找到对应的模式。以*结尾,并跳出case
  • case需要搭配esac结尾

示例:

echo '输入 1 到 4 之间的数字:'
echo '你输入的数字为:'
read num
case $num in
    1)  echo '你选择了 1'
    ;;
    2)  echo '你选择了 2'
    ;;
    3)  echo '你选择了 3'
    ;;
    4)  echo '你选择了 4'
    ;;
    *)  echo '你没有输入 1 到 4 之间的数字'
    ;;
esac

执行结果:

输入 1 到 5 之间的数字:4
你输入的数字为 4!
输入 1 到 5 之间的数字:8
你没有输入 1 到 4 之间的数字

8.3 for循环

shell中的for循环调用格式

for var in item1 item2 ... itemN
do
    command1
    command2
    ...
    commandN
done

# 写成一行同样使用分号将语句分开 

需要注意的是:

  • in列表中可以包含替换、字符串和文件名等
  • in列表是可选的,如果默认不适用,将会循环使用命令行中的位置参数

示例:

#!/bin/bash
for num in 1 2 3 4 5
do
echo "the num is ${num}"
done

结果:

The value is: 1
The value is: 2
The value is: 3
The value is: 4
The value is: 5

示例:

#!/bin/bash
for str in This is a string
do
    echo $str
done

结果:

This
is
a
string

8.4 while循环

shell中的while循环用于不断执行一系列命令,也用于从输入文件中读取数据,调用格式如下:

while condition
do
    command
done

示例:


#!/bin/bash
num=1
while(( $num<=5 ))
do
    echo $num
    let "num++"
done

只需要知道shell中while循环的格式,同样可以做到和C语言中一样, 使用while循环进行判定或者判断键盘循环,甚至无限循环等,如下使用while循环读取键盘操作

echo -n '输入你最喜欢的歌名: '
while read SONG
do
    echo "啊!$SONG 真是一首好歌"
done

9 Shell 函数

9.1 定义函数

linux中的shell同样可以定义函数,然后在函数中调用执行相关的shell命令,完成功能。

[ function ] funname [()]
{
    action;
    [return int;]
}

说明:

  • 可以带function fun() 定义,也可以直接fun() 定义,不带任何参数。
  • 参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)
  • 注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。

示例:

#!/bin/bash
demoFun(){
    echo "这是我的第一个函数"
}
echo "-----函数开始执行-----"
demoFun
echo "-----函数执行完毕-----"
#!/bin/bash
addFun(){
        echo "请输入第一个数:"
        read num1
        echo "请输入第二个数:"
        read num2
        echo "输入的两个数为:${num1}和${num2}"
        return $(($num1+$num2))
}
echo "-----函数开始执行-----"
addFun
echo "两个数字的和为:$?"       ## 使用$?获取上一条指令的结果
echo "-----函数执行完毕-----"

9.2 函数参数

此外想要使用shell函数传递参数时,需要在函数体的内部,通过 $n 的形式来获取参数的值。

示例:

#!/bin/bash
FunParam(){
    echo "输入第一个参数 $1 !"
    echo "输入第二个参数 $2 !"
    echo "输入第十个个参数 $10 !"
    echo "参数总数共 $# 个!"
    echo "作为一个字符串输出所有参数 $* !"
}
FunParam 1 2 3 4 5 6 7 8 9 10

-- 系统备份

-- 软硬连接

版权声明:原创作品,允许转载,转载时务必以超链接的形式表明出处和作者信息。否则将追究法律责任。来自海汼部落-阿布都的都,http://hainiubl.com/topics/76024
回复数量: 1
  • wtf2012
    2023-09-26 09:37:46

    非常详细,比CSDN某些周排名20后的博主给力。

暂无评论~~
  • 请注意单词拼写,以及中英文排版,参考此页
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
  • 支持表情,可用Emoji的自动补全, 在输入的时候只需要 ":" 就可以自动提示了 :metal: :point_right: 表情列表 :star: :sparkles:
  • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif,教程
  • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
Ctrl+Enter