shell介绍
概念:
用户编写的shell命令通过shell解释器解释后交给linux内核去执行. shell是一个程序(解释器程序) 用户和linux内核的桥梁.
Shell 是一个 C 语言编写的脚本语言,它是用户与 Linux 的桥梁,用户输入命令交给 Shell 处理 Shell 将相应的操作传递给内核(Kernel),内核把处理的结果输出给用户。
shell编程通常指的是学习shell命令语法后,利用这套语法开发脚本程序,操作、访问内核服务。 而不是使用C语言去编写一个shell程序。
开发步骤:
1.编写sh脚本文件
2.执行sh脚本文件
shell编程开发步骤
在哪里编写?
只要能进行文本编辑的地方都可以写 ,linux上常使用vim编辑器开发。
需要编译吗?
不需要编译。
如何执行?
需要shell语法解释器执行,不过不需要安装shell解释器,Linux系统中集成了很多种类的shell解释器。
shell解释器:
默认: /bin/bash
常见Shell解释器如下
sh:全称是 Bourne shell,由 AT&T 公司的 Steve Bourne开发,为了纪念他,就用他的名字命名了。sh 是UNIX 上的标准 shell,很多 UNIX 版本都配有 sh。sh 是第一个流行的 Shell。
csh: 全称是C shell,它是sh之后另一个广为流传的shell是由柏克莱大学的Bill Joy设计的,这个shell的语法有点类似C语言,所以才得名为C shell ,简称为csh。
Bash:全称是bash shell,它是Linux的默认shell。由GNU组织开发,是各种Linux发行版默认配置的 shell。bash兼容sh,针对sh编写的Shell代码可以不加修改地在bash中运行。
shell变量
用户变量: 用户变量在编程过程中使用量最多. 环境变量: 环境变量主要是在程序运行时需要设置的.比如/ect/profile 特殊变量: 执行sh文件和函数传递的参数变量
shell变量是一种很“弱”的变量,默认情况下,一个变量保存一个串
shell中有3种变量:用户变量、环境变量、特殊变量
用户变量在编程过程中使用量最多
环境变量主要是在程序运行时需要设置
特殊变量在对参数判断和命令返回值判断时会使用
变量的定义语法:
变量名=变量值
变量的定义需遵循的规则
1)变量名可以由字母、数字和下画线组成,但是不能以数字开头,不能使用关键字
2)在 Bash中,变量的默认类型都是字符串型,如果要进行数值运算,则必须使用特殊命令
3)变量用等号"="连接值,"="左右两侧不能有空格。
4)变量值建议用中如果有空格,则需要使用单引号或双引号包含,如 test="hello world!"
5)在变量值中,可以使用转义符"\"。
用户变量:
定义变量:变量名=变量值 注意等号两边不能有空格! 访问变量:$变量名 或 ${变量名} 修改变量值:变量名=变量值 建议提取变量的时候 使用{}标识变量的边界范围 修改变量为只读变量: readonly 变量名 定义只读变量并赋值: readonly 变量名=变量值 删除变量: unset 变量名 # 只读变量无法删除.连接断开就会消失.
定义变量:变量名=变量值 注意等号两边不能有空格!
访问变量:$变量名 或 ${变量名}
修改变量值:变量名=变量值
建议提取变量的时候 使用{}标识变量的边界范围
删除变量: unset 变量名
修改变量为只读变量: readonly 变量名
定义只读变量并赋值: readonly 变量名=变量值
注意:
只读变量不能够进行删除 只会随着生命周期结束而结束
对应shell命令来说 生命周期就是窗口关闭
对应shell脚本来说 生命周期就是shell执行结束
系统变量:
在讲解which命令的时候,我们知道使用的一系列命令其实本质上就是一个个的可执行程序。
比如,cd命令的本体就是:/usr/bin/cd 这个程序文件。
我们是否会有疑问,为何无论当前工作目录在哪里,都能执行:/usr/bin/cd这个程序呢?
这就是环境变量的作用啦。
环境变量是操作系统(Windows、Linux、Mac)在运行的时候,记录的一些关键性信息,用以辅助系统运行。
当shell程序启动时,都自动设置一组变量,这组变量就是环境变量。shell中的所有命令都可以使用这些变量,环境变量可以在/etc/profile中设置,环境变量的名字习惯上使用大写字母
在Linux中执行:env命令即可查看当前系统中记录的环境变量,环境变量是一种Key=Value型结构,即名称和值
那么为设么我们无论当前工作目录是什么,都能执行/usr/bin/cd这个程序? 这个就是借助环境变量中:PATH这个项目的值来做到的。
当执行任何命令,都会按照顺序,从上述路径中搜索要执行的程序的本体 比如执行cd命令,就从第四个目录/usr/bin中搜索到了cd命令,并执行!
自行设置环境变量
特殊变量:
我们可以在执行 Shell 脚本时,向脚本传递参数,这时候可以使用特殊变量来获取参数
在执行Shell程序脚本时,可以向shell脚本动态传递参数。好处是某些配置属性不用写死在脚本中。
动态传递参数的方式: sh shell脚本文件 参数1 参数2 ...
Shell常用的特殊变量在shell脚本内部支持接收参数并使用:
$0 | 当前程序的名称 |
---|---|
$n | $1表示第一个参数,$2表示第二个参数,以此类推 |
$# | 命令行参数的个数 |
$* | 以“参数1 参数2 。。。”形式保存所有参数 |
shell字符串
# 字符串可以使用三种方式来定义.建议使用双引号来定义. s1=hello s2='hello' s3="hello" # 双引号中的$具有特殊含义.单引号则没有. echo "${s3}" -> hello echo '${s3}' -> ${s3} #原样输出
一般来说,在编程语言中,字符串是使用最多的数据类型,shell也不例外;
shell中字符串定义可以使用单引号、可以使用双引号、也可以不使用引号;
推荐使用双引号定义字符串,方便在字符串中实现变量的提取操作。
双引号括起来的内容有"$"等都拥有特殊含义
单引号括起来的内容都是普通字符
shell 反引号的使用
反引号可以执行里面的命令: mydate=date echo $mydate -> date mydate=`date` echo $mydate -> 2024年 08月 17日 星期六 14:47:36 CST
` 反引号
英文状态下如何输入?按下ESC按键下面那个按键。
功能:执行反引号里面的命令。
#需求:把date命令执行的结果赋值给nowtime变量
#如果没有反引号 理解为字符串
#使用反引号 理解为执行命令 把命令的结果进行赋值
shell命令、shell脚本
命令、脚本本质上都是属于shell;
shell命令倾向于在linux命令行中使用,适合逻辑简单场景;
shell脚本倾向于在文件中编写,适合复杂逻辑处理。
shell脚本文件一般以.sh结尾
文件第一行一般为#!/bin/bash
#以shell命令执行
#编写shell脚本 执行脚本
shell脚本执行方式
方式一:sh执行
格式: sh 脚本
注意: 需要进入脚本的所在工作目录,然后使用对应的sh命令来执行脚本,
这种执行方式,脚本文件不需要具有可执行权限。
方式二:相对路径执行
格式: ./脚本
注意: 需要先进入到脚本所在的目录,然后使用 ./脚本方式执行,
这种执行方式,必须保证脚本文件具有可执行权限。
方式三:绝对路径执行
格式: /绝对路径/脚本
注意: 需要使用脚本的绝对路径中执行,指的是直接从根目录/到脚本目录的绝对路径,
这种执行方式,必须保证脚本文件具有可执行权限。
执行脚本方式案例1
--------------编写sh脚本---------------------------- [root@zhangsan opt]# vim a1.sh [root@zhangsan opt]# ll 总用量 4 -rw-r--r--. 1 root root 56 8月 17 15:06 a1.sh drwxr-xr-x. 2 root root 6 3月 26 2015 rh --------------sh命令执行[无需权限]---------------------------- [root@zhangsan opt]# sh a1.sh zhangsan zhangsan ---------------相对路径执行[需要权限]------------------------------ [root@zhangsan opt]# ./a1.sh -bash: ./a1.sh: 权限不够 [root@zhangsan opt]# chmod 777 a1.sh [root@zhangsan opt]# ll 总用量 4 -rwxrwxrwx. 1 root root 56 8月 17 15:06 a1.sh drwxr-xr-x. 2 root root 6 3月 26 2015 rh [root@zhangsan opt]# ./a1.sh zhangsan zhangsa ------------------绝对路径执行[需要权限]----------------------------------- [root@zhangsan opt]# cd / [root@zhangsan /]# /opt/a1.sh zhangsan zhangsan
特殊变量使用案例2
[root@cent1 test]# vim binzi2.sh #!/bin/bash echo "当前脚本文件名称为:$0" echo "传入的第一个参数为:$1" echo "传入的第一个参数为:$2" echo "传入的第一个参数为:$3" echo "传入的参数一共$#个" echo "所有参数为:$*" [root@cent1 test]# sh binzi2.sh 张三 18 男 当前脚本文件名称为:binzi2.sh 传入的第一个参数为:张三 传入的第一个参数为:18 传入的第一个参数为:男 传入的参数一共3个 所有参数为:张三 18 男
shell控制流程:扩展
shell运算方式:
$((运算式)) $[运算式] ---------------------------------------- [root@zhangsan opt]# echo $a 10 [root@zhangsan opt]# echo $b 20 [root@zhangsan opt]# echo $a+$b 10+20 [root@zhangsan opt]# echo $(($a+$b)) 30 [root@zhangsan opt]# echo $[$a+$b] 30
if介绍:
if的基本介绍以及if格式案例操作 概述:Shell提供了丰富的语句判断方式,包括数字,字符串和文件。 语句判断相关, 具体如下:数字:运算符 说明-eq 检测两个数是否相等,相等返回 true。-ne 检测两个数是否不相等,不相等返回 true。-gt 检测左边的数是否大于右边的,如果是,则返回 true。-lt 检测左边的数是否小于右边的,如果是,则返回 true。-ge 检测左边的数是否大于等于右边的,如果是,则返回 true。-le 检测左边的数是否小于等于右边的,如果是,则返回 true。 字符串:判断符 说明-n STRING 字符串长度不为零-z STRING 字符串长度为0= 判断两个字符串是否一样!= 判断两个字符串是否不一样 文件判断符 说明-f 存在且是普通文件-d 存在且是目录-h 存在且是符号链接 -e 文件存在 –r 文件存在并且可读–w 文件存在并且可写–x 文件存在并且可执行逻辑运算:&& 并且 左右两个条件都为真结果才是真.|| 或者 左右两个条件有一个为真结果就是真.! 非 真变假,假变真
IF语法1:
if 语句语法格式:if [ condition ] //条件, 条件要用 [] 包裹. condition左右必须有空格thencommand1 //符合条件后, 就会执行这里的内容command2...commandN fi //注意: 不允许将以上格式 写成一行
案例
案例1: 判断当前系统是否有多个ssh进程,如果有则打印truetest1.sh //这是SHELL脚本文件, 以下是里边的内容. #!/bin/bashif [ $(ps -ef | grep -c "ssh") -gt 1 ] //这里的-c就是count的意思, 即: 统计个数的. then echo "true" fi//上述的if也可以改成: if [ `ps -ef | grep -c "ssh"` -gt 1 ] 这种写法.案例2: 判断/media/cdrom目录是否存在,若不存在就去创建这个目录test2.sh //这是SHELL脚本文件, 以下是里边的内容. #!/bin/bash DIR="/media/cdrom" if [ ! -d $DIR ] then mkdir -p $DIR fi
IF语法2:
if else 语法格式: if [ condition ] //条件, 用[]包裹thencommand1 //符合条件后, 执行的内容command2...commandN elsecommand //不符合条件后, 执行的内容. fi
案例:
实例:需求1: 根据年龄判断是否成年test3.sh //这个是Shell脚本文件, 以下是它里边的内容. #!/bin/bashread -p "Enter your age(1~100):" age //read表示读取用户录入的数据, -p "这里写的是提示信息", age表示把录入的数据给此变量.if [ $age -ge 18 ]thenecho '已经成年!'elseecho '未成年!'fi
IF和test相结合
if else 语句经常与 test命令 结合使用解释:test 命令允许你做各种测试并在测试成功或失败时返回它的退出状态码(为0表示为真,为1表示为假)。使用这个状态码,可以让 Bash 对测试的结果做出反应。test 命令的语法为: //采用 test 的方式, 来替代[]test EXPRESSION或[ EXPRESSION ]
案例:
test4.sh //这个是Shell脚本文件, 以下是它里边的内容. #!/bin/bashnum1=$[2*3] #//这两个数字可以改为键盘录入的, 即: read -p "请录入第1个整数: " anum2=$[1+5]if test $[num1] -eq $[num2]thenecho '两个数字相等!'elseecho '两个数字不相等!'fi 小技巧: //设置Linux的制表符为4个空格. vim /etc/vimrc, 然后粘贴如下内容到文件中即可. set ts=4set expandtabset autoindent
IF语法3:
if和if_else的相关的结构说明和操作案例 if else-if else 语法格式:if condition1 //条件1thencommand1 //满足条件1后, 执行的内容elif condition2 //条件2then command2 //满足条件2后, 执行的内容elsecommandN //所有条件都不满足, 则执行这里.fi
案例1
案例1: 以下实例判断两个变量是否相等:
test5.sh //这个是Shell脚本文件, 以下是它里边的内容.
#!/bin/bash echo "请输入a的值:" read a echo "请输入b的值:" read b if [ $a == $b ] then echo "a 等于 b" elif [ $a -gt $b ] then echo "a 大于 b" elif [ $a -lt $b ] then echo "a 小于 b" else echo "没有符合的条件" fi 上述的代码可以写成如下的形式: //即: 结合test一起使用 read -p "请录入第1个整数: " a read -p "请录入第2个整数: " b if test $a -eq $b thenecho "a 等于 b" elif test $a -gt $b thenecho "a 大于 b" elif test $a -lt $b thenecho "a 小于 b" elseecho "没有符合的条件" fi
案列2
案例2: 输入成绩,判断成绩“优”“良”“中”
test6.sh //这个是Shell脚本文件, 以下是它里边的内容.
#!/bin/bash # 方式1 read -p "Enter your score(0-100):" n #-p参数表示给出提示信息 if [ $n -ge 85 ] && [ $n -le 100 ] ; thenecho "优" elif [ $n -ge 70 ] && [ $n -le 84 ] ; thenecho "良" elif [ $n -ge 60 ] && [ $n -le 69 ] ; thenecho "中" elseecho "差" fi 方式2: #!/bin/bash read -p "请录入你的成绩: " s if test $s -ge 85 && test $s -le 100 thenecho "优秀" elif test $s -ge 70 && test $s -lt 85 thenecho "良好" elif test $s -ge 60 && test $s -lt 70 thenecho "中等" elseecho "差" fi 注意: 一个条件使用一个[]包裹, 多个条件之间可以用 &&,||这样的逻辑运算符连接.
for循环语法1
for循环的第一种格式的操作案例 概述:与其他编程语言类似,Shell支持for循环。 格式1: 字符符型循环 //可以把这种for循环理解为Java中的 增强for循环.格式:for 变量 in 值1 值2 值3…do程序done解释:当变量值在列表里,for循环即执行一次所有命令,使用变量名获取列表中的当前取值。命令可为任何有效的shell命令和语句。in列表可以包含替换、字符串和文件名。in列表是可选的,如果不用它,for循环使用命令行的位置参数。
实例: 需求1: 顺序输出当前列表中的数字:test7.sh //这个是Shell脚本文件, 以下是它里边的内容!/bin/bashfor loop in 1 2 3 4 5doecho "The value is: $loop"done输出结果:The value is: 1The value is: 2The value is: 3The value is: 4The value is: 5 ------------------------------------------------ 需求2: 顺序输出字符串中的字符test8.sh //这个是Shell脚本文件, 以下是它里边的内容#!/bin/bashfor str in 'This is a string'doecho $strdone 输出结果:This is a string -------------------------------------------------- 需求3: 打印/root目录下所有文件的名字 test9.sh //这个是Shell脚本文件, 以下是它里边的内容#!/bin/bash for file in $(ls /root)do echo $file done
for循环语法2
for循环第二种格式的操作案例 格式2: 数字型循环 //可以把这种for循环理解为Java中的 普通for循环.格式:for ((初始值;循环控制条件;变量变化))do程序done格式解释:初始值:在循环开始时,需要给某个变量赋予初始值,如 i=1。循环控制条件:用于指定变量循环的次数,如 i<=100,则只要 i 的值小于等于 100,循环就会继续。变量变化:每次循环之后,变量该如何变化,如 i=i+1,代表每次循环之后,变量的值都加 1。 //语法二和其他语言中的 for 循环类似,也就是事先决定循环次数的固定循环。
实例: 需求1: 求1-100的和test10.sh //这个是Shell脚本文件, 以下是它里边的内容 #!/bin/bashsum=0#从1加到100for ((i=1; i<=100; i++))#定义循环100次do#每次循环给变量sum赋值# sum=$(($sum + $i)) #这样写可以# sum=$[$sum + $i] #也可以这样写sum=`expr $sum + $i` #还可以这样写doneecho "总和为$sum"
while循环语法
while循环的基本操作语法: 概述:while循环用于不断执行一系列命令,也用于从输入文件中读取数据;命令通常为测试条件。 格式为:while 条件do程序done
案例:需求1: 以下是一个基本的while循环,测试条件是:如果int小于等于5,那么条件返回真。int从0开始,每次循环处理时,int加1。运行上述脚本,返回数字1到5,然后终止。test11.sh //这个是Shell脚本文件, 以下是它里边的内容 写法1: #!/bin/bashnum=1while (( num <= 5 ))doecho $num#num=$[$num + 1] #这个格式可以优化成如下的写法let "num++" #这个表示num变量值的值+1done 写法2:#!/bin/bashnum=1while [ $num -le 5 ]doecho $num# let "num++" #这个格式可以优化成如下的写法num=$[$num + 1]done 运行脚本,输出:12345//上述循环中使用了let命令,它用于执行一个或多个表达式,变量计算中不需要加上 $ 来表示变量,具体可查阅:Bash let 命令。需求2: 求1-100的和test12.sh //这个是Shell脚本文件, 以下是它里边的内容//这个是Shell脚本文件, 以下是它里边的内容#!/bin/bashsum=0a=1 while [ $a -le 100 ]do# sum=$[ $sum + $a ]# sum=$(($sum + $a ))#sum=`expr $sum + $a`let sum=sum+a //let用于执行一个或多个表达式,变量计算中不需要加上 $ 来表示变量.let a++done echo "总和为: $sum"
死循环写法
如何实现死循环操作 方式1: //推荐使用这种方式, 用的人比较多. while :docommanddone 方式2:while truedocommanddone 方式3:for (( ; ; ))docommanddone
示例代码; #!/bin/bash for ((;;))doecho "我是死循环!"sleep 1 //休眠1秒.done //小技巧: 如何让SHELL程序进入休眠状态. sleep n //n是数字, 单位是秒, 例如: sleep 1, 就是休眠1秒.
扩展案例
08. 扩展案例: 打印1-10之间的数字, 遇到3的倍数就结束循环.for num in 1 2 3 4 5 6 7 8 9 10doif [ `expr $num % 3` == 0 ]thenbreakelseecho $num fi done09. 扩展案例: 打印1-10之间的数字, 遇到3的倍数就结束循环. for num in 1 2 3 4 5 6 7 8 9 10 doif [ `expr $num % 3` == 0 ]thencontinueelseecho $num fi done
shell综合案例
shell的综合案例_猜数字小游戏 游戏规则为:程序内置一个1到100 之间的数字作为猜测的结果,由用户猜测此数字。用户每猜测一次,由系统提示猜测结果:大了、小了或者猜对了;直到用户猜对结果,则提示游戏结束。 代码:guess_number.sh //这个是Shell脚本文件, 以下是它里边的内容 #!/bin/bash #生成100以内的随机数 提示用户猜测 猜对为止 #random 系统自带,值为0-32767任意数 #随机数1-100 num=$[RANDOM%100+1] #read 提示用户猜数字 #if判断 while :doread -p "计算机生成了一个 1‐100 的随机数,你猜: " caiif [ $cai -eq $num ]thenecho "恭喜,猜对了"exitelif [ $cai -gt $num ]thenecho "不巧,猜大了"elseecho "不巧,猜小了"fidone