Shell解释器,变量,运算符及脚本基础

shell解释器

linux中有很多的shell解释器,默认使用为bash,路径为/bin/bash,其他还有很多种shell,在etc/shells中可以查看系统中所有的shell解释器

 [root@localhost bin]# cat /etc/shells
 /bin/sh
 /bin/bash
 /usr/bin/sh
 /usr/bin/bash
 /bin/tcsh
 /bin/csh
 /bin/ksh
 /bin/rksh

可以通过直接输入解释器的名称来打开不同的解释器使用,再通过exit退出当前解释器,回到上一级解释器

 [root@localhost bin]# ksh
 # tcsh
 [root@localhost /bin]# exit
 exit
 # exit

需要其他解释器的时候也可以用之前的yum命令直接安装,bash解释器有很多优点,比如他支持用tab智能补充命令,支持管道(|)和重定向(> >>),支持查询历史命令并且直接使用历史命令等等

shell脚本基础格式及使用

shell脚本基础格式

shell脚本方便我们重复多次相同或者相似的操作,一般存于/opt中,有一定的格式要求

 [root@localhost bin]# cd /opt
 [root@localhost opt]# vim ty1.sh
 //先进入目录/opt,然后使用vim编辑创建一个.sh文件编辑
 #!/bin/bash
 #这是一个shell脚本,用来打印helloworld
 echo helloworld
 //进入编辑模式后,输入以上内容,第一行为解释器及路径,第二行为注释,第三行为脚本执行内容,输入完成保存退出

基础脚本就编写完了,然后就是执行脚本的几种方式

方式1,赋予权限后直接使用路径执行

赋予该脚本执行的权限(+x),并且直接输入路径即可运行

 [root@localhost opt]# cat ty1.sh
 #!/bin/bash
 #这是一个shell脚本,用来打印helloworld
 echo helloworld
 [root@localhost opt]# chmod +x ty1.sh
 [root@localhost opt]# ./ty1.sh
 helloworld

方式2,使用指定解释器运行

基础格式:解释器名 脚本路径

 [root@localhost opt]# sh ty1.sh
 helloworld

这种方式其实是创建了一个解释器的子进程,在子进程中运行,我们所用的bash解释器为主进程,所以一旦脚本中有了打开目录类似的操作,就会导致操作无法正常运行,因为其打开文件也在子程序中,而非主程序中

 [root@localhost opt]# cat ty2.sh
 #!/bin/bash
 #这是一个创建并打开目录acc的脚本
 mkdir acc
 cd acc
 [root@localhost opt]# sh ty2.sh
 [root@localhost opt]# find acc
 acc

这里目录acc已经被脚本创建成功,但是cd acc命令没有成功运作,当前目录仍旧在/opt,因为这一步在子进程sh中完成并且关闭,主进程就无法进入该目录,解决这一问题就要用到source

方式3,source命令

基础格式:source 脚本路径

和方式2不同,source实际上使用默认的解释器,不会开启子进程,所以就可以解决方式2中的问题,接着上面的代码

 [root@localhost opt]# rm acc -rf
 [root@localhost opt]# source ty2.sh
 [root@localhost acc]#

先删除刚才创建的文件acc,然后使用source运行代码,cd acc这一步就成功执行了,当前目录进入了acc中

shell变量

自定义变量

变量命名的时候有一些规则,命名时只能使用英文,数字,下划线,并且首字符不能用数字开头,且等号左右两侧一格位置不能有空格,不能使用系统的关键字(ls,cd等等)来命名,且变量的值如果有空格,那么就需要用引号括起来(a="a b"),单双引号区别在界定符位置一起总结

 //错误的变量命名
 [root@localhost opt]# a = 12
 bash: a: 未找到命令...
 [root@localhost opt]# 22a=12
 bash: 22a=12: 未找到命令...
 [root@localhost opt]# a=a b
 bash: b: 未找到命令...

一个变量设置好之后,就是调用这个变量的值,使用符号$,如果在变量后面需要紧接其他字母或数字等干扰因素,将变量用[]括起来,示例:

 [root@localhost opt]# a=998
 [root@localhost opt]# echo $a
 998
 [root@localhost opt]# echo $acm
 ​
 [root@localhost opt]# echo $[a]cm
 998cm

使用uset 变量名,可以直接删除指定变量

环境变量

环境变量为系统已经定义好的全局变量,使用的时候直接调用即可,常用的有

  • USER 当前用户名

  • HOME 当前用户家目录

  • UID 当前用户UID

  • SHELL 当前用户解释器

  • PWD 当前位置

  • PS1 一级提示符

  • PS2 二级提示符

这里一级提示符与二级提示符:

 [root@localhost opt]# PS1=tishifu
 tishifuls
 a    acc   helloworld.sh   ty2.sh
 tishifu

一级提示符为每次输入代码前的那一排显示的内容,这里将一级提示符改为tishifu之后,可以看到ls仍旧可以正常运行。而当一行的长度不足以装下全部代码的时候,我们可以输入\后回车,会切换至下一行输入,最前面的>即为二级提示符

 [root@localhost /]# cd \
 > /opt
 [root@localhost opt]#

位置变量

$n为第n个参数值,$*为命令行中所有参数,把所有参数看做一个整体,$@则把所有参数看做单个个体对待,$#为参数个数,$$为随机进程号,$?判断上一步是否执行成功,成功为0,非0为失败

 [root@localhost opt]# cat ty3.sh
 #!/bin/bash
 #这是一个位置变量参考脚本
 echo $1
 echo $3
 echo $6
 echo $*
 echo $$
 echo $#
 echo $?
 [root@localhost opt]# source ty3.sh 1 2 3 4 5 6 7 8 9
 1
 3
 6
 1 2 3 4 5 6 7 8 9
 35691
 9
 0

界定符

常见的三种界定符,双引号,单引号,反撇号

单引号''会把所有的字符全部当做普通字符处理

 [root@localhost opt]# a=10
 [root@localhost opt]# echo $a
 10
 [root@localhost opt]# echo '$a'
 $a

双引号""用于界定范围,会将特殊字符按照特殊字符处理

 [root@localhost opt]# echo $adddddddd$a
 10
 [root@localhost opt]# echo "$a"dddddddd$a
 10dddddddd10

反撇号``会获取后面命令的结果而非命令本身,也可以用$()代替反撇号

 [root@localhost opt]# a=date
 [root@localhost opt]# echo $a
 date
 [root@localhost opt]# a=`date`
 [root@localhost opt]# echo $a
 2021年 09月 25日 星期六 10:04:36 CST
 [root@localhost opt]# a=$(date)
 [root@localhost opt]# echo $a
 2021年 09月 25日 星期六 10:05:15 CST

read指令

read指令可以让脚本获得用户处的输入,让脚本成为交互式

基础格式:read -p "显示的内容" 存到哪个变量中

示例:在.sh脚本中编写如下代码

 #!/bin/bash
 #创建账号并配置密码
 read -p "请输入要创建的账号名" username
 stty -echo
 read -p "请输入密码" passwd
 stty echo
 useradd $username
 echo $passwd | passwd --stdin $username

其中,stty -echo可以让用户输入的内容无法在屏幕上显示出来,用于保护密码隐私,输入完密码后styy echo可以让内容重新显示

 [root@localhost abc]# source zhanghao.sh
 请输入要创建的账号名bc
 请输入密码更改用户 bc 的密码 。
 passwd:所有的身份验证令牌已经成功更新。

运行结果如上,交互处有两处,为输入账号和密码的部分,且密码也如预期被隐藏

shell中的运算

expr命令

expr命令可实现基础整数之间的加减乘除,使用时运算符两边必须有空格

 [root@localhost abc]# expr 9 + 3
 12
 [root@localhost abc]# expr 9 / 3
 3
 [root@localhost abc]# expr 9 '*' 3
 27
 [root@localhost abc]# expr 9 % 2
 1

需要注意,expr结果会自动输出,只能输出整数,且使用乘法时要加上单引号

$[]形式

$[]形式不会自己输出结果,需要结合echo使用

 [root@localhost abc]# echo $[ 9 + 3 ]
 12
 [root@localhost abc]# echo $[ 9 * 3 ]
 27

let指令

let用于变量的创建而非结果的输出

 [root@localhost abc]# let a=5+3
 [root@localhost abc]# echo $a
 8
 [root@localhost abc]# let a++
 [root@localhost abc]# echo $a
 9

数字关系运算符

顾名思义,其只适用于数字或者参数为数字的变量之间的大小关系比对

-eq 相等输出真

-ne 不相等输出真

-gt 左大右输出真

-lt 左小右输出真

-ge 左大于等于右输出真

-le 左小于等于右输出真

使用示例:

 [root@localhost abc]# a=1
 [root@localhost abc]# b=1
 [root@localhost abc]# [ $a -eq $b ]
 [root@localhost abc]# echo $?
 0
 [root@localhost abc]# a=2
 [root@localhost abc]# [ $a -eq $b ]
 [root@localhost abc]# echo $?
 1

逻辑运算符

!取反,[!false]则为true

-o 或运算,[$a -eq $b -o $c -eq $d],有一个表达式为真则返回真

-a 与运算,[$a -eq $b -a $c -eq $d],全真返回真

逻辑与:[ a -eq a ] && ls,前为真,执行ls

[ a -eq b ] && ls,前为假,不执行ls

逻辑或:[ a -eq a ] || ls,前为真,不执行ls

[ a -eq b ] || ls,前为假,执行ls

字符串运算符

字符串运算符作用对象为字符串

== 检测$a,$b是否相等,相等返回真 [ $a == $b ]

!= 检测$a,$b是否相等,不等返回真

-z 检测字符串长度是否为0,为0返回真 [ -z $a ]

-n 检测字符串长度是否为0,不为0返回真

str 检测字符串是否为空,不为空返回真

检测返回值仍然用前面的echo $?方法

shell脚本中的if,for,while

if

if的基础语法为

if 条件;then

满足条件就执行指令1

elif 条件;then

满足条件就执行指令2

else

其他情况下执行指令

fi

直接看例子来得快:

 [root@localhost abc]# cat panduan.sh
 #!/bin/bash
 #用户名判断
 read -p "请输入要判断的用户名" username
 ​
 num=$(cat /etc/passwd | grep $username | wc -l)
 ​
 if [ $num == 0 ];then
 echo "对不起,该用户不在系统中"
 ​
 else
 echo "该用户在系统中"
 fi

这是一个判断用户名是否在本系统中的if代码,结合了前面的read指令和运算关系,其中管道| wc -l 作用为输出满足条件的数量

 [root@localhost abc]# cat if.sh
 #!/bin/bash
 #if分支
 read -p "请输入我的成绩" chengji
 if [ $chengji -le 100 ] && [ $chengji -ge 60 ];then
 echo "考的不错啊"
 elif [ $chengji -lt 60 ] && [ $chengji -ge 0 ];then
 echo "这次不太行啊"
 else
 echo "?你是怎么做到的?"
 fi

这是一个if多分支的判断成绩,按照输入成绩的不同输出不同的结果

for

for的基础语法为

for 变量名称 in 值1 值2 值3

do

执行内容

done

一样直接上例子:

 [root@localhost abc]# cat xunhuan2.sh
 #!/bin/bash
 #这是一个简单循环
 for i in 1 2 3
 do
 echo "这是第$i次循环了"
 done
 [root@localhost abc]# source xunhuan2.sh
 这是第1次循环了
 这是第2次循环了
 这是第3次循环了

for循环的数值位置,可以填写其他内容,只是代表此次循环i为多少

 [root@localhost abc]# cat xunhuan3.sh
 #!/bin/bash
 #这是一个简单循环
 for i in abc cdc weq
 do
 echo "这次循环内容为$i"
 done
 [root@localhost abc]# source xunhuan3.sh
 这次循环内容为abc
 这次循环内容为cdc
 这次循环内容为weq

当循环次数要求特别多的时候,可以采用省略号的方式来决定次数

 [root@localhost abc]# cat xunhuan4.sh
 #!/bin/bash
 #这是一个简单循环
 for i in {1..10}
 do
 echo "这是第$i次循环了"
 done
 [root@localhost abc]# source xunhuan4.sh
 这是第1次循环了
 这是第2次循环了
 这是第3次循环了
 这是第4次循环了
 这是第5次循环了
 这是第6次循环了
 这是第7次循环了
 这是第8次循环了
 这是第9次循环了
 这是第10次循环了

最终你还可以结合外部输入来做到想循环几次就循环几次,使用seq命令

 [root@localhost abc]# cat xunhuan.sh
 #!/bin/bash
 #该代码为循环的示例
 read -p "请输入想要循环多少次" cishu
 for i in $(seq $cishu)
 do
         echo "这是第$i次循环"
 done
 [root@localhost abc]# source xunhuan.sh
 请输入想要循环多少次5
 这是第1次循环
 这是第2次循环
 这是第3次循环
 这是第4次循环
 这是第5次循环

while

while的基础语法为

while 条件为真

do

执行相应指令

done

也直接上列子吧,RANDOM可以生成一个随机数

 [root@localhost abc]# echo $RANDOM
 4520
 [root@localhost abc]# echo $RANDOM
 27502
 [root@localhost abc]# echo $RANDOM
 19444

那么就可以编写一个猜数字小游戏,利用while让他一直循环,我们一直猜,再利用前面shell中的运算和if做到比大小提示,猜中就break

 
 [root@localhost abc]# cat cai.sh
 #!/bin/bash
 #猜数字小游戏
 x=$[ RANDOM % 200 ]
 while [ 1 -eq 1 ]
 do
 read -p "猜一个1到200之间的数" shu
 if [ $x -lt $shu ];then
         echo "数字猜大了"
 elif [ $x -gt $shu ];then
         echo "数字猜小了"
 else
         echo "恭喜你,猜中了嗷"
         break
 fi
 done
 [root@localhost abc]# source cai.sh
 猜一个1到200之间的数100
 数字猜大了
 猜一个1到200之间的数50
 数字猜小了
 猜一个1到200之间的数75
 数字猜小了
 猜一个1到200之间的数88
 数字猜小了
 猜一个1到200之间的数94
 数字猜大了
 猜一个1到200之间的数92
 恭喜你,猜中了嗷

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值