数组
定义数组IPS=(192.168.2.1 192.168.2.2 192.168.2.3) #空格隔开,不能用逗号隔开[root@lianxi ~]# echo $IPS #默认为数组第一个192.168.2.11.显示数组所有元素 [root@lianxi ~]# echo ${IPS[@]} 192.168.2.1 192.168.2.2 192.168.2.32.显示数组元素个数 [root@lianxi ~]# echo ${#IPS[@]} 3 [root@lianxi ~]# echo ${#IPS[1]} #第一个元素的个数 113.显示数组的某一个元素 [root@lianxi ~]# echo ${IPS[1]} #下标从0开始 192.168.2.2
转义和引用
# 注释 ; 分号 分割两个命令的\ 转移符号 \n \t \r 和 \$ \" \\ "不完全引用"和'完全引用,所见即所得'和``
运算符
在shell用用的非常少,性能不高
-
赋值运算符
=
用于算数和字符串赋值,使用unset取消;算符运算符有 -
算数运算符
+ - * / ** % 或者 expr 4+5
expr只支持整数类型计算,不支持浮点数;[root@lianxi ~]# expr 4+5 #+号两边没空格,则当成字符串了4+5[root@lianxi ~]# expr 4 + 5 #可以支持加减乘除等等,只能是整数计算,并且得到的也是整数9[root@lianxi ~]# numb=`expr 4 + 5` #注意是反引号,这样将计算结果赋值给变量;
-
数字常量 let “变量名=变量值”,使用0开头的为八进制,0x开头的为十六进制;直接将计算的值赋值给变量就用let
let a=4+5,shell中很少用let,使用下面双括号更方便
-
双圆括号
((a=10)) 或者((a=4+5))或者((a++))或者echo $((4+5))或者 a=$((4+5))
变量运算
1整数运算,expr $(()),$[]
,不支持小数运算
[root@web01 ~]# expr 5 + 4 +边一定要有空格,9[root@web01 ~]# echo $((5+4))9[root@web01 ~]# echo $[ 4 + 5 ]9如果有小数,就需要用到bc或者awk也可以awk 'BEGIN{print 5/2}'
特殊符号大全
-
引号
"",'',``
-
括号
(),(()),$()单独使用圆括号会产生一个子shell(xyz=123)数组初始化IPS=(ip1 ip2 ip3)$()和``都是取值的let的简写就是(())[],[[]]单独使用方括号是测试(test)或数组元素功能,test的简写两个方括号表示测试表达式;这组符号与先前的 [] 符号,基本上作用相同,但她允许在其中直接使用 || 与&& 逻辑等符号。< > 数值比较 单独一个就是重定向符号{}输出范围 echo {1..9}文件复制 cp /etc/passwd{,.bak}
-
运算和逻辑符号
(( 5 > 4 && 6 < 8 )) #两个判断都为真,则为真,$?(( 5 > 4 || 6 > 8 )) #只要有个为真,则为真(( ! 5 > 4 ))
-
转义符号
-
其他符号
分号;分隔命令ifdown eth0 ; ifup eth0 使用分号是将两个命令一起传递给主机,比&&符号强,更比分开执行强;在case语句中使用两个;;对分号进行转义,或者在if [] ;then 写在同一行,分隔命令,显示更加整洁: 占位符,相当于passls *.sh 和 ls ?.sh
完全路径执行
定义个sh,然后赋予x权限,使用绝对路径去执行[root@lianxi ~]# vim /tmp/9.shif [ $USER = root ];then echo "user root"else echo "other user"fi[root@lianxi ~]# /tmp/9.sh #绝对路径去执行作者回复: /tmp/9.sh完整路径运行相当于外部命令, 这种相当于执行了一个bash命令,然后把9.sh里的每条语句运行一次,然后执行exit
if
if和case都是流程控制语句;
#判断当前用户是否为root用户[root@lianxi ~]# [ $UID = 0 ] #这里的0是字符串类型,等同于[ $UID = '0' ][root@lianxi ~]# [ $UID -eq 0 ] #这里的0是数值类型 [root@lianxi ~]# [ $USER = root ] #这里值字符串判断在shell里面即使以数字0-9方式使用,变量仍然当做字符串处理,UID是系统定义好的变量,一定是整数,所以这里用= 或者 -eq 都可以实现判断用户id的功能if后面还可以跟命令[root@lianxi ~]# cat 1.sh #/bin/bashif pwd;then #pwd命令一定会执行成功,所以返回值为0,继续往后执行 echo "hello"fi[root@lianxi ~]# bash 1.sh /roothello如果传入的变量有个特殊字符,就用""阔起来 [ "$pos" = "help" ] if [] ;thenelsefiif [];thenelif [];thenelsefi###########################if grep $1 /etc/paswd;thenecho "这里也是可以的,你需要弄清楚"fi#取反if [ ! 5 -lt 3 ];then #叹号一定要搞清楚!-r -w -x只要user,group,other其中一个人有对应的权限就为真!三元表达式[ -d /test ] && {echo "yes"} || {echo "NO.."} #和if..else是一样的效果!
还有if..else,if嵌套等等;
如果输入1或者backup都是退出,那么通过if是无法进行判断的,这时候就需要用到了case,
case可以进行多条件进行判断
CASE
case可以通过if来实现,但是case更加方便;
case "$变量" in "情况1") 命令..;; "情况2") 命令..;; *) 命令;;esac我们在systemctl start,stop,restart,disabled等等就是用的case实现的;case "$1" in 三个选项执行同样的结果,这种复杂判断,只能用case进行! 1|'start'|'START') # | 不要包含在里面,要不然会被当做一个整体,所以分出来!!!! echo "start....." ;; 'stop'|'STOP') echo "stop...." ;; *) echo "Usage: $0 {start|stop}" ;;esac
case可以嵌套,还可以在每个选项中进行if判断!
颜色输出
source /etc/init.d/functions#就是将echo 变为actionaction "成功" /bin/true action "失败" /bin/false
正则匹配
正则匹配一定要在双括号中使用[[]]
,单括号是无法进行正则匹配的
判断用户输入的数据必须是数字read -p "Please input you number:" ret[[ $ret =~ ^[0-9]+$ ]] || { echo "必须输入数字才可以!" ; exit; } #加上{}意义就不一样了,表示这两个为一个整体
for循环语法
for 变量 in [ 取值列表 ]do 循环体donefor var in a1 a2 a3 a4 ...do;donestr="192.168.1.1 192.168.1.2 192.168.1.3" #后面这些是字符串,但是for循环能够根据空格分割他们虽然后面是一个字符串,但是for循环依然能够循环他们,根据空格分割;换成其他符号就不行了!for i in $str;doecho $idone列表生成:{1..9}for 参数 in 列表 #这是列表,如果想控制循环次数,看下面的for语句dodone 使用反引号或者$()方式,命令的执行结果当做列表进行处理,for i in {1..100}这是可以的for i in {1..$(ls -l|wc -l)} 这中后面当做字符串了,所以无法执行;+ for i in '{1..$(ls -l|wc -l)}'+ echo '{1..6}'{1..6}
使用反引号或者$()方式,命令的执行结果当做列表进行处理;按空格分割!
for循环自定义分隔符
默认情况下空格作为分隔符,通过IFS来自定义分隔符
[root@web01 ~]# cat /etc/hosts127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4::1 localhost localhost.localdomain localhost6 localhost6.localdomain6[root@web01 ~]# cat 1.sh for i in `cat /etc/hosts`;do echo $idone[root@web01 ~]# bash 1.sh 127.0.0.1localhostlocalhost.localdomainlocalhost4localhost4.localdomain4::1localhostlocalhost.localdomainlocalhost6localhost6.localdomain6可以看到每一行都取出来后,然后按空格分隔成列表;如果想每一行为一个单位输出怎么办?#以冒号最为分隔符 IFS=:#以冒号\分号和双引号作为字段分隔符 IFS=;:"#以换行符作为字段分割符 IFS=$'\n'[root@web01 ~]# cat 1.sh #!/bin/bashIFS=$'\n'for i in `cat /etc/hosts`;do echo $idone[root@web01 ~]# bash 1.sh 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4::1 localhost localhost.localdomain localhost6 localhost6.localdomain6这样就能满足要求了!for i in $(cat /etc/passwd);do echo $i | grep "root" #过滤出root的行 grep "root" $i #这种写法是错的!!!他把$i当做文件名了!!!!!!!!!!!!!!!!!!!!所以错了!!done
没有回复内容