程序:算法+数据结构 数据:是程序的核心 数据结构:数据在计算机中的类型和组织方式 算法:处理数据的方式
#面向过程语言 作一件事情,排出个步骤,第一步干什么,第二步干什么,若是出现状况A,作什么处理,如 果出现了状况B,作什么处理 问题规模小,能够步骤化,循序渐进处理 以指令为中心,数据服务于指令 C,shell #面向对象语言 一种认识世界、分析世界的方法论。将万事万物抽象为各类对象 类是抽象的概念,是万事万物的抽象,是一类事物的共同特征的集合 对象是类的具象,是一个实体 问题规模大,复杂系统 以数据为中心,指令服务于数据 java,C#,python,golang等
计算机:运行二进制指令 编程语言:人与计算机之间交互的语言。分为两种:低级语言和高级语言 低级编程语言: 机器:二进制的0和1的序列,称为机器指令。与天然语言差别太大,难懂、难写 汇编:用一些助记符号替代机器指令,称为汇编语言 如:ADD A,B 将寄存器A的数与寄存器B的数相加获得的数放到寄存器A中 汇编语言写好的程序须要汇编程序转换成机器指令 汇编语言稍微好理解,即机器指令对应的助记符,助记符更接近天然语言 高级编程语言: 编译:高级语言-->编译器-->机器代码文件-->执行,如:C,C++ 解释:高级语言-->执行-->解释器-->机器代码,如:shell,python,php,JavaScript,perl 编译和解释型语言
自动化经常使用命令 执行系统管理和故障排除 建立简单的应用程序 处理文本或文件
#执行方法1 [root@centos8 ~]#bash /data/hello.sh #执行方法2 [root@centos8 ~]#cat /data/hello.sh | bash #执行方法3 [root@centos8 ~]#chmod +x /data/hello.sh 但你写了一个脚本却没法被执行是由于你的hash里面没有这个路径,路径没法被查到,就是在环境变量里面没法被查到,要写到环境变量里面 并且还要用 .激活一下 #绝对路径 [root@centos8 ~]#/data/hello.sh #相法路径 [root@centos8 ~]#cd /data/ [root@centos8 ~]#./hello.sh #执行方法4,本方法能够实现执行远程主机的shell脚本 [root@centos8 ~]#yum -y install httpd [root@centos8 ~]#systemctl start httpd [root@centos8 ~]#mv /data/hello.sh /var/www/html/ [root@centos8 ~]#curl -s http://www.wanghua.com/hello.sh|bash #执行互联网上的脚本 -s 能够隐藏下载的信息 [root@centos8 ~]#wget -qO - http://www.wangxiaochun.com/testdir/hello.sh |bash hello, world Hello, world! 调用别人写的脚本,将将脚本放在服务器上,调用服务器上的脚本
[root01:52 PMcentos7 ]#cat a.sh #!/bin/bash echo -e "\033[1;32m 开始备份 \033[0m" sleep 3 cp -a /etc /back/`date +%F_%T` echo -e "\033[1;32m 备份完成 \033[0m"
只检测脚本中的语法错误,但没法检查出命令错误,但不真正执行脚本javascript
bash -n /path/to/some_script
调试并执行php
bash -x /path/to/some_script -x:真正执行了的,每次执行一行,执行的结果就显示一下
总结:脚本错误常见的有三种html
语法错误,会致使后续的命令不继续执行,能够用bash -n 检查错误,提示的出错行数不必定是准java
确的node
命令错误,默认后续的命令还会继续执行,用bash -n 没法检查出来 ,可使用 bash -x 进行观察python
逻辑错误:只能使用 bash -x 进行观察linux
变量表示命名的内存空间,将数据放在内存空间中,经过变量名引用,获取数据c++
变量类型: 内置变量,如:PS1,PATH,UID,HOSTNAME,$$(当前进程),BASHPID,PPID(父进程),$?,HISTSIZE 用户自定义变量 不一样的变量存放的数据不一样,决定了如下 1. 数据存储方式 2. 参与的运算 3. 表示的数据范围 变量数据类型: 字符 数值:整型、浮点型,bash 不支持浮点数
#静态和动态语言 静态编译语言:使用变量前,先声明变量类型,以后类型不能改变,在编译时检查,如:java,c 动态编译语言:不用事先声明,可随时改变类型,如:bash,Python #强类型和弱类型语言 强类型语言:不一样类型数据操做,必须通过强制转换才同一类型才能运算,如java , c# , python 如:参考如下 python 代码 print('magedu'+ 10) 提示出错,不会自动转换类型 print('magedu'+str(10)) 结果为magedu10,须要显示转换类型 弱类型语言:语言的运行时会隐式作数据类型转换。无须指定类型,默认均为字符型;参与运算会 自动进行隐式类型转换;变量无须事先定义可直接调用 如:bash ,php,javascript
不能使程序中的保留字:如:if, for 只能使用数字、字母及下划线,且不能以数字开头,注意:不支持短横线 “ - ”,和主机名相反 见名知义,用英文单词命名,并体现出实际做用,不要用简写,如:ATM 统一命名规则:驼峰命名法, studentname,大驼峰StudentName 小驼峰studentName 变量名大写:STUDENT_NAME 局部变量小写 函数名小写
变量的生效范围等标准划分变量类型golang
普通变量:生效范围为当前shell进程;对当前shell以外的其它shell进程,包括当前shell的子shell 进程均无效 环境变量:生效范围为当前shell进程及其子进程 本地变量:生效范围为当前shell进程中某代码片段,一般指函数
直接字串:name='root' 变量引用:name="$USER" 命令引用:name=`COMMAND` 或者 name=$(COMMAND)
注意:变量赋值是临时生效,当退出终端后,变量会自动删除,没法持久保存,脚本中的变量会随着脚面试
本结束,也会自动删除
弱引用和强引用 "$name " 弱引用,其中的变量引用会被替换为变量值 '$name ' 强引用,其中的变量引用不会被替换为变量值,而保持原字符串
[root@centos8 ~]#TITLE='cto' [root@centos8 ~]#echo $TITLE cto [root@centos8 ~]#echo I am $TITLE I am cto [root@centos8 ~]#echo "I am $TITLE" I am cto [root@centos8 ~]#echo 'I am $TITLE' I am $TITLE [root@centos8 ~]#NAME=$USER [root@centos8 ~]#echo $NAME root [root@centos8 ~]#USER=`whoami` [root@centos8 ~]#echo $USER root [root@centos8 ~]#FILE=`ls /run` [root@centos8 ~]#echo $FILE agetty.reload atd.pid auditd.pid autofs.fifo-misc autofs.fifo-net console cron.reboot cryptsetup dbus faillock fsck initctl initramfs lock log mount NetworkManager plymouth rsyslogd.pid screen sepermit setrans sshd.pid sssd.pid sudo systemd tmpfiles.d tuned udev user utmp vmware [root@centos8 ~]#FILE=/etc/* 命令的执行结果 [root@centos8 ~]#echo $FILE /etc/adjtime /etc/aliases /etc/alternatives /etc/anacrontab /etc/at.deny /etc/audit /etc/authselect /etc/autofs.conf /etc/autofs_ldap_auth.conf
[root03:27 PMcentos7 ]#title=cto [root03:33 PMcentos7 ]#name=wang [root03:33 PMcentos7 ]#title=$name [root03:34 PMcentos7 ]#echo $name wang [root03:34 PMcentos7 ]#echo $title wang [root03:35 PMcentos7 ]#name=wo [root03:35 PMcentos7 ]#echo $name wo [root03:35 PMcentos7 ]#echo $title wang [root03:35 PMcentos7 ]#name=ow [root03:37 PMcentos7 ]#echo $name ow [root03:37 PMcentos7 ]# wo这个字符串没有人使用了,就是一块垃圾了,会被回收
[root@centos8 ~]#seq 10 1 2 3 4 5 6 7 8 9 10 [root@centos8 ~]#NUM=`seq 10` [root@centos8 ~]#echo $NUM 1 2 3 4 5 6 7 8 9 10 [root@centos8 ~]#echo "$NUM" #加双引号才能保留多行格式 1 2 3 4 5 6 7 8 9 10 [root03:43 PMcentos7 ]#name=" > wang > zhang > li > " [root03:44 PMcentos7 ]#echo $name wang zhang li [root03:44 PMcentos7 ]#echo "$name" wang zhang li [root03:44 PMcentos7 ]#name="wang > zhang > zhao > li" [root03:48 PMcentos7 ]#echo $name wang zhang zhao li [root03:48 PMcentos7 ]#echo "$name" wang zhang zhao li [root03:48 PMcentos7 ]#
set
unset <name> # 跟的是变量名,无须要加$ [root@centos8 ~]#NAME=mage [root@centos8 ~]#TITLE=ceo [root@centos8 ~]#echo $NAME $TITLE mage ceo [root@centos8 ~]#unset NAME TITLE [root@centos8 ~]#echo $NAME $TITLE
[root04:29 PMcentos7 ]#cat parent.sh #!/bin/bash NAME=name echo $NAME /data/son.sh [root04:29 PMcentos7 ]#cat son.sh #!/bin/bash echo " 调用父进程的变量 $NAME" NAME="myvalue" echo "调用本身的变量 $NAME" [root04:29 PMcentos7 ]#/data/parent.sh name 调用父进程的变量 ( #子进程没法调用父进程的变量) 调用本身的变量 myvalue [root04:29 PMcentos7 ]#/data/son.sh 调用父进程的变量 调用本身的变量 myvalue [root04:29 PMcentos7 ]# [root04:29 PMcentos7 ]#vim parent.sh (添加export之后,子进程就调用父进程的环境变量) 1 #!/bin/bash 2 export NAME=name 3 echo $NAME 4 /data/son.sh [root04:48 PMcentos7 ]#/data/parent.sh name 调用父进程的变量 name 调用本身的变量 myvalue 父进定义的环境变量,子进程能使用,当子进程本身定义的变量和父进程定义的环境变量一致的时候,子进程优先使用本身的变量
环境变量: 可使子进程(包括孙子进程)继承父进程的变量,可是没法让父进程使用子进程的变量 一旦子进程修改从父进程继承的变量,将会新的值传递给孙子进程 通常只在系统配置文件中使用,在脚本中较少使用 #声明并赋值 export name=VALUE declare -x name=VALUE #或者分两步实现 name=VALUE export name
[root@centos8 data]#NAME=mage [root@centos8 data]#AGE=20 [root@centos8 data]#echo $NAME mage [root@centos8 data]#echo $AGE 20 [root@centos8 data]#echo $NAME $AGE mage 20 [root@centos8 data]#echo $NAME$AGE mage20 [root@centos8 data]#echo $NAME_$AGE #由于下划线是能够当作变量名的,将$NAME_ 认为是一个变量 20 [root@centos8 data]#echo ${NAME}_$AGE mage_20
系统全部的环境变量,只是列环境变量
[root05:03 PMcentos7 ]#echo $$ 3365 [root05:12 PMcentos7 ]#bash [root05:12 PMcentos7 ]#echo $$ 5155 [root05:12 PMcentos7 ]#echo $PPID $SHLVL:嵌套深度 $$:当前的进程的PID $PPID:父进程的PID 3365 [root05:12 PMcentos7 ]#echo $SHLVL 2 [root05:13 PMcentos7 ]#bash [root05:14 PMcentos7 ]#echo $SHLVL 3 [root05:14 PMcentos7 ]#
[root05:48 PMcentos7 ]#CD=hostname [root05:48 PMcentos7 ]#$CD centos7
[root03:11 PMcentos7 ]#cat b.sh #!/bin/bash echo -e "\033[1;31m ---------------------主机信息----------------------- \033[0m" echo -e "\033[1;32m主机名:`hostname` \033[0m" echo -e "\033[1;32mIP地址:`ifconfig ens33 |grep -Eo '([0-9]{1,3}\.){3}[0-9]{1,3}' |head -1 `\033[0m" echo -e "\033[1;32m发行版本号:`cat /etc/redhat-release`\033[0m" echo -e "\033[1;32m内核版本:`uname -r` \033[0m " echo -e "\033[1;32mCPU信息:`lscpu |grep -i "model name"|tr -s ' ' |cut -d: -f2`\033[0m" echo -e "\033[1;32m内存的使用状况:`free -h |grep -iE "mem"|tr -s ' ' : |cut -d: -f2`\033[0m" echo -e "\033[1;32m磁盘的使用状况:`lsblk |grep "^sd" |awk '{print $4}' ` \033[0m" echo -e "\033[1;31m-------------------------------------------------------\033[0m"
只读变量:只能声明定义,但后续不能修改和删除,即常量
声明只读变量:
[root06:05 PMcentos7 ]#type declare declare is a shell builtin #申明只读变量 readonly name declare -r name #查看只读变量: readonly [-p] declare -r [root@centos8 ~]#readonly PI=3.14159 [root@centos8 ~]#echo $PI 3.14159 [root@centos8 ~]#PI=3.14 -bash: PI: readonly variable [root@centos8 ~]#unset PI -bash: unset: PI: cannot unset: readonly variable [root@centos8 ~]#echo $PI 3.14159 [root@centos8 ~]#exit #退出之后变量就消失了 logout Connection closed by foreign host.
位置变量:在bash shell中内置的变量, 在脚本代码中调用经过命令行传递给脚本的参数
$1, $2, ... 对应第1个、第2个等参数,shift [n]换位置 $0 命令自己,包括路径 $* 传递给脚本的全部参数,所有参数合为一个字符串 $@ 传递给脚本的全部参数,每一个参数为独立字符串 $# 传递给脚本的参数的个数 注意:$@ $* 只在被双引号包起来的时候才会有差别 #清空全部位置变量 set --
[root@centos8 ~]#cat /data/scripts/arg.sh #!/bin/bash echo "1st arg is $1" echo "2st arg is $2" echo "3st arg is $3" echo "10st arg is ${10}" echo "11st arg is ${11}" echo "The number of arg is $#" echo "All args are $*" echo "All args are $@" echo "The scriptname is `basename $0`" `basename $0`不显示路径名 [root@centos8 ~]#bash /data/scripts/arg.sh {a..z} 1st arg is a 2st arg is b 3st arg is c 10st arg is j 11st arg is k The number of arg is 26 All args are a b c d e f g h i j k l m n o p q r s t u v w x y z All args are a b c d e f g h i j k l m n o p q r s t u v w x y z The scriptname is arg.sh
[root06:24 PMcentos7 ]#cat rm.sh #!/bin/bash STA="echo -e \033[1;31m" END="\033[0m" DIR=/tmp/`date +%F_%T` mkdir $DIR mv $* $DIR $STA MOVE $* TO $DIR $END
[root@centos8 scripts]#cat file.sh #!/bin/bash echo "file.sh:1st arg is $1" [root@centos8 scripts]#cat f2.sh #!/bin/bash echo "f2.sh:all args are $@" echo "f2.sh:all args are $*" ./file.sh "$@" [root@centos8 scripts]#cat f1.sh #!/bin/bash echo "f1.sh:all args are $@" echo "f1.sh:all args are $*" ./file.sh "$*" [root@centos8 scripts]#./f1.sh a b c f1.sh:all args are a b c f1.sh:all args are a b c file.sh:1st arg is a b c # 嵌套之后$* 是全部的参数 $@是一个参数 [root@centos8 scripts]#./f2.sh a b c f2.sh:all args are a b c f2.sh:all args are a b c file.sh:1st arg is a
进程执行后,将使用变量 $? 保存状态码的相关数字,不一样的值反应成功或失败,$?取值范例 0-255
$?的值为0 #表明成功 $?的值是1到255 #表明失败 [root@centos8 scripts]#curl http://www.wangxiaochun.com &> /dev/null [root@centos8 scripts]#echo $? 0 ping -c1 -W1 hostdown &> /dev/null echo $? #最近一条命令的执行结果
注意:
脚本中一旦遇到exit命令,脚本会当即终止;终止退出状态取决于exit命令后面的数字
若是未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码
展开命令执行顺序 把命令行分红单个命令词 展开别名 展开大括号的声明{} 展开波浪符声明 ~ 命令替换$() 和 `` 再次把命令行分红命令词 展开文件通配*、?、[abc]等等 准备I/0重导向 <、> 运行命令 反斜线(\)会使随后的字符按原意解释 echo Your cost: \$5.00 Your cost: $5.00
set 命令:能够用来定制 shell 环境 $- 变量 h:hashall,打开选项后,Shell 会将命令所在的路径hash下来,避免每次都要查询。经过set +h将h选 项关闭 i:interactive-comments,包含这个选项说明当前的 shell 是一个交互式的 shell。所谓的交互式shell, 在脚本中,i选项是关闭的 m:monitor,打开监控模式,就能够经过Job control来控制进程的中止、继续,后台或者前台执行等 B:braceexpand,大括号扩展 H:history,H选项打开,能够展开历史列表中的命令,能够经过!感叹号来完成,例如“!!”返回上最近的 一个历史命令,“!n”返回第 n 个历史命令 [root08:02 PMcentos7/boot ]#ls /etc/redhat-release /etc/redhat-release [root08:03 PMcentos7/boot ]#cat $_ echo $_是前一条命令的最后一个参数 CentOS Linux release 7.9.2009 (Core) [root@centos8 ~]#echo $- himBHs [root08:05 PMcentos7/boot ]#set +h [root08:05 PMcentos7/boot ]#echo $- imBH [root08:05 PMcentos7/boot ]#hash #这样之后hash就被禁用了 -bash: hash: hashing disabled [root08:05 PMcentos7/boot ]# [root08:05 PMcentos7/boot ]#set -h #恢复hash功能 [root08:07 PMcentos7/boot ]#hash hits command 2 /usr/bin/cat 4 /usr/bin/ls [root08:07 PMcentos7/boot ]#echo $- #恢复原状 himBH [root@centos8 ~]#set +B 关闭{}的功能 [root@centos8 ~]#echo $- imHs [root@centos8 ~]#echo {1..10} {1..10}
-u 在扩展一个没有设置的变量时,显示错误信息, 等同set -o nounset -e 若是一个命令返回一个非0退出状态值(失败)就退出, 等同set -o errexit -o option 显示,打开或者关闭选项 显示选项:set -o 打开选项:set -o 选项 关闭选项:set +o 选项 -x 当执行命令时,打印命令及其参数,相似 bash -x
[root08:08 PMcentos7/boot ]#set -o allexport off braceexpand on emacs on errexit off #出现错误不退出 errtrace off functrace off hashall on histexpand on history on ignoreeof off interactive-comments on keyword off monitor on noclobber off noexec off noglob off nolog off notify off nounset off onecmd off physical off pipefail off posix off privileged off verbose off vi off xtrace off [root08:18 PMcentos7~ ]#set -o errexit on #开启功能,出现错误之后退出 [root08:18 PMcentos7~ ]#set -o |grep errexit errexit on [root08:21 PMcentos7~ ]#bash f.sh line1 f.sh: line 4: xxx: command not found [root08:21 PMcentos7~ ]#cat f.sh #!/bin/bash set -e echo line1 set -e 安全,可是一条命令不成功,后面的都不执行 xxx echo line2
[root08:32 PMcentos7~ ]#cat b.sh #!/bin/bash DIR=/data1 rm -rf /data/tmp/$DIR1/* 由于没有$DIR1这个变量,没有定义的变量 [root08:33 PMcentos7~ ]#mkdir /data/tmp/ [root08:33 PMcentos7~ ]#touch /data/tmp/a [root08:33 PMcentos7~ ]#touch /data/tmp/b [root08:33 PMcentos7~ ]#bash b.sh [root08:34 PMcentos7~ ]#ls /data/tmp/ [root08:39 PMcentos7~ ]#cat b.sh #!/bin/bash set -u DIR=/data1 rm -rf /data/tmp/$DIR1/* [root08:38 PMcentos7~ ]#bash b.sh b.sh: line 4: DIR1: unbound variable 加了-u 之后就不准哪些未知的变量 因此工做中基于安全考虑,脚本中加 set -ue
printf "指定的格式" "文本1" ”文本2“…… %s 字符串 %f 浮点格式 %b 相对应的参数中包含转义字符时,可使用此替换符进行替换,对应的转义字符会被转 义 %c ASCII字符,即显示对应参数的第一个字符 %d,%i 十进制整数 %o 八进制值 %u 不带正负号的十进制值 %x 十六进制值(a-f) %X 十六进制值(A-F) %% 表示%自己
[root@centos8 ~]#printf "%s\n" 1 2 3 4 1 2 3 4 [root@centos8 ~]#printf "%f\n" 1 2 3 4 1.000000 2.000000 3.000000 4.000000 #.2f 表示保留两位小数 [root@centos8 ~]#printf "%.2f\n" 1 2 3 4 1.00 2.00 3.00 4.00 [root@centos8 ~]#printf "(%s)" 1 2 3 4;echo (1)(2)(3)(4) [root@centos8 ~]#printf " (%s) " 1 2 3 4;echo "" (1) (2) (3) (4) [root@centos8 ~]#printf "(%s)\n" 1 2 3 4 (1) (2) (3) (4) [root@centos8 ~]#printf "%s %s\n" 1 2 3 4 1 2 3 4 [root@centos8 ~]#printf "%s %s %s\n" 1 2 3 4 1 2 3 4 #%-10s 表示宽度10个字符,左对齐 [root@centos8 ~]#printf "%-10s %-10s %-4s %s \n" 姓名 性别 年龄 体重 小明 男 20 70 小红 女 18 50 姓名 性别 年龄 体重 小明 男 20 70 小红 女 18 50 #将十进制的17转换成16进制数 [root@centos8 ~]#printf "%X" 17 11[root@centos8 ~]# #将十六进制C转换成十进制 [root@centos8 ~]#printf "%d\n" 0xC 12 [root@centos8 ~]#VAR="welcome to Magedu";printf "\033[31m%s\033[0m\n" $VAR welcome to Magedu [root@centos8 ~]#VAR="welcome to Magedu";printf "\033[31m%s\033[0m\n" "$VAR" welcome to Magedu
shell 支持算术运算,但只支持整数,不支持小数
bash中的算术运算
+ - * / % 取模,即取余数,示例:9%4=1,5%3=2 ** 乘方
乘法符号有些场景中须要转义
+= i+=10 至关于 i=i+10 -= i-=j 至关于 i=i-j *= /= %= ++ i++,++i 至关于 i=i+1 -- i--,--i 至关于 i=i-1
实现算术运算:
(1) let var=算术表达式 (2) ((var=算术表达式)) 和上面等价 [root@centos8 ~]#let i=10*2 [root@centos8 ~]#echo $i 20 [root@centos8 ~]#((j=i+10)) [root@centos8 ~]#echo $j 30 [root09:29 AMcentos8 ~]#let i=10*2 [root09:29 AMcentos8 ~]#((j=i+10)) [root09:30 AMcentos8 ~]#echo $j 30 (3) var=$[算术表达式] (4) var=$((算术表达式)) (5) var=$(expr arg1 arg2 arg3 ...) (6) declare –i var = 数值 (7) echo '算术表达式' | bc
内建的随机数生成器变量:
$RANDOM 取值范围:0-32767 [root08:53 PMcentos7~ ]#echo $RANDOM 16020 [root08:57 PMcentos7~ ]#echo $RANDOM 26272
#生成 0 - 49 之间随机数 echo $[$RANDOM%50] #随机字体颜色 [root@centos8 ~]#echo -e "\033[1;$[RANDOM%7+31]mhello\033[0m" magedu [root09:25 PMcentos7~ ]#echo -e "\e[1;$[RANDOM%7+31]mhello\033[0m" hello
[root08:59 PMcentos7~ ]#n=10 [root09:00 PMcentos7~ ]#m=20 [root09:00 PMcentos7~ ]#sum=$m+$n [root09:00 PMcentos7~ ]#echo $sum 20+10 [root09:00 PMcentos7~ ]#let sum=$m+$n [root09:02 PMcentos7~ ]#echo $sum 30 [root09:02 PMcentos7~ ]#n=30 [root09:02 PMcentos7~ ]#let sum=$m+$n [root09:02 PMcentos7~ ]#echo $sum 50
[root09:05 PMcentos7~ ]#let result=RANDOM%50 [root09:05 PMcentos7~ ]#echo $result 24 [root09:05 PMcentos7~ ]#let result=RANDOM%50+1 [root09:06 PMcentos7~ ]#echo $result 48
[root09:06 PMcentos7~ ]#i=10 [root09:08 PMcentos7~ ]#let i++ [root09:08 PMcentos7~ ]#echo $i 11 [root09:08 PMcentos7~ ]#let i++ [root09:08 PMcentos7~ ]#echo $i 12 [root09:08 PMcentos7~ ]#let i-- [root09:08 PMcentos7~ ]#echo $i 11 [root09:08 PMcentos7~ ]#let ++i [root09:09 PMcentos7~ ]#echo $i 12 [root09:09 PMcentos7~ ]#let ++i [root09:09 PMcentos7~ ]#echo $i 13
[root09:09 PMcentos7~ ]#i=10;let j=i++;echo j=$j i=$i #赋值给j之后再加 j=10 i=11 [root09:13 PMcentos7~ ]#i=10;let j=++i;echo j=$j i=$i #加完了赋给j j=11 i=11
[root09:33 PMcentos7~ ]#expr 2 + 3 5 [root09:33 PMcentos7~ ]#expr 2 * 3 expr: syntax error [root09:34 PMcentos7~ ]#expr 2 / 3 0 [root09:34 PMcentos7~ ]#expr 23 / 3 7 [root09:34 PMcentos7~ ]#expr 27 / 3 9 [root09:34 PMcentos7~ ]#expr 2 \* 3 乘法被误认为通配符,转义 6
[root09:36 PMcentos7~ ]#echo 2*3 |bc 6 [root09:39 PMcentos7~ ]#echo "scale=3;20/3" |bc 6.666
[root09:40 PMcentos7~ ]#i=10 [root09:43 PMcentos7~ ]#j=20 [root09:43 PMcentos7~ ]#declare -i result=i*j [root09:44 PMcentos7~ ]#echo $result 200
true, false
1, 0
#与:&:和0相与,结果为0,和1相与,结果保留原值 1 与 1 = 1 1 与 0 = 0 0 与 1 = 0 0 与 0 = 0 #或:|:和1相或结果为1,和0相或,结果保留原值 1 或 1 = 1 1 或 0 = 1 0 或 1 = 1 0 或 0 = 0 #非:! ! 1 = 0 ! true ! 0 = 1 ! false #异或:^ 异或的两个值,相同为假,不一样为真。两个数字X,Y异或获得结果Z,Z再和任意二者之一X异或,将得出 另外一个值Y 1 ^ 1 = 0 1 ^ 0 = 1 0 ^ 1 = 1 0 ^ 0 = 0
[root@centos8 ~]#true [root@centos8 ~]#echo $? 0 [root@centos8 ~]#false [root@centos8 ~]#echo $? 1 [root@centos8 ~]#! true [root@centos8 ~]#echo $? 1 [root@centos8 ~]#! false [root@centos8 ~]#echo $? 0 #交换两个值 [root@centos8 ~]#x=10;y=20;temp=$x;x=$y;y=$temp;echo x=$x,y=$y x=20,y=10 [root@centos8 ~]#x=10;y=20;x=$[x^y];y=$[x^y];x=$[x^y];echo x=$x,y=$y x=20,y=10
短路与 CMD1 短路与 CMD2 第一个CMD1结果为真 (1),第二个CMD2必需要参与运算,才能获得最终的结果 第一个CMD1结果为假 (0),总的结果一定为0,所以不须要执行CMD2 短路或 CMD1 短路或 CMD2 第一个CMD1结果为真 (1),总的结果一定为1,所以不须要执行CMD2 第一个CMD1结果为假 (0),第二个CMD2 必需要参与运算,,才能获得最终的结果
条件测试:判断某需求是否知足,须要由测试机制来实现,专用的测试表达式须要由测试命令辅助完成
测试过程
,实现评估布尔声明,以便用在条件性环境下进行执行
若真,则状态码变量 $? 返回0
若假,则状态码变量 $? 返回1
条件测试命令
test EXPRESSION [ EXPRESSION ] #和test 等价,建议使用 [ ] [[ EXPRESSION ]] ========================================================================== [root11:40 PMcentos7~ ]#type [ 中括号自己就是一个内部命令 [ is a shell builtin [root11:45 PMcentos7~ ]#help [ [: [ arg... ] Evaluate conditional expression. This is a synonym for the "test" builtin, but the last argument must be a literal `]', to match the opening `['. [[ ... ]]: [[ expression ]] Execute conditional command. Returns a status of 0 or 1 depending on the evaluation of the conditional expression EXPRESSION. Expressions are composed of the same primaries used by the `test' builtin, and may be combined using the following operators: ( EXPRESSION ) Returns the value of EXPRESSION ! EXPRESSION True if EXPRESSION is false; else false EXPR1 && EXPR2 True if both EXPR1 and EXPR2 are true; else false EXPR1 || EXPR2 True if either EXPR1 or EXPR2 is true; else false When the `==' and `!=' operators are used, the string to the right of the operator is used as a pattern and pattern matching is performed. When the `=~' operator is used, the string to the right of the operator is matched as a regular expression. The && and || operators do not evaluate EXPR2 if EXPR1 is sufficient to determine the expression's value. Exit Status: 0 or 1 depending on value of EXPRESSION.
注意:EXPRESSION先后必须有空白字符
帮助:
[root10:56 PMcentos7~ ]#cat a xiaoing=20 xiaohong=18 xiaoqiang=22 方法一: [root11:08 PMcentos7~ ]#cut -d"=" -f2 a |tr -s "\n" + |cut -d'+' -f1-3 20+18+22 [root11:01 PMcentos7~ ]#cut -d"=" -f2 a |tr -s "\n" + |cut -d'+' -f1-3 |bc 60 方法二: [root11:14 PMcentos7~ ]#cut -d"=" -f2 a |tr -s "\n" + |grep -Eo "([0-9]+\+){2}[0-9]+"|bc 60 方法三 [root11:14 PMcentos7~ ]#cut -d"=" -f2 a |tr -s "\n" + 20+18+22+[root11:16 PMcentos7~ ]#cut -d"=" -f2 a |tr -s "\n" + |grep -Eo ".*[0-9]+" |bc 60 方法四: [root10:11 AMcentos8 ~]#awk -F"=" '{print $2}' |paste -sd+ |bc 60
[root11:47 PMcentos7~ ]#test -v n [root11:52 PMcentos7~ ]#echo $? 0 [root11:52 PMcentos7~ ]#echo $n 30 [root11:54 PMcentos7~ ]#name= [root11:54 PMcentos7~ ]#test -v name [root11:54 PMcentos7~ ]#echo $? 0 [root11:55 PMcentos7~ ]#echo $name [root11:55 PMcentos7~ ]# [root11:55 PMcentos7~ ]#unset name [root11:57 PMcentos7~ ]#test -v name [root11:57 PMcentos7~ ]#echo $? 1 [root11:58 PMcentos7~ ]#hi="hi" [root11:59 PMcentos7~ ]#[ -v hi ] test和中括号等价 [root11:59 PMcentos7~ ]#echo $? 0
-eq 是否等于 -ne 是否不等于 -gt 是否大于 -ge 是否大于等于 -lt 是否小于 -le 是否小于等于
[root@centos8 ~]#i=10 [root@centos8 ~]#j=8 [root@centos8 ~]#[ $i -lt $j ] 即便是数字也要加$ [root@centos8 ~]#echo $? 1 [root@centos8 ~]#[ $i -gt $j ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#[ i -gt j ] -bash: [: i: integer expression expected
test和 [ ]用法 -z STRING 字符串是否为空,没定义或空为真,不空为假, -n STRING 字符串是否不空,不空为真,空为假 STRING 同上 STRING1 = STRING2 是否等于,注意 = 先后有空格,没有空格是赋值,有空格是比较 STRING1 != STRING2 是否不等于 > ascii码是否大于ascii码 < 是否小于 [[]] 用法,建议,当使用正则表达式或通配符使用,通常状况使用 [ ] == 左侧字符串是否和右侧的PATTERN相同 注意:此表达式用于[[ ]]中,PATTERN为通配符 =~ 左侧字符串是否可以被右侧的正则表达式的PATTERN所匹配 注意: 此表达式用于[[ ]]中;扩展的正则表达式
[root@centos8 ~]#unset str [root@centos8 ~]#[ -z "$str" ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#str="" [root@centos8 ~]#[ -z "$str" ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#str=" " [root@centos8 ~]#[ -z "$str" ] [root@centos8 ~]#echo $? 1 [root@centos8 ~]#[ -n "$str" ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#unset str [root@centos8 ~]#[ -n "$str" ] [root@centos8 ~]#echo $? 1 [root@centos8 ~]#[ "$str" ] [root@centos8 ~]#echo $? 1 [root@centos8 ~]#str=magedu [root@centos8 ~]#[ "$str" ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#str=magedu [root@centos8 ~]#[ "$str" ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#str1=magedu [root@centos8 ~]#str2=mage [root@centos8 ~]#[ $str1 = $str2 ] [root@centos8 ~]#echo $? 1 [root@centos8 ~]#str2=magedu [root@centos8 ~]#[ $str1 = $str2 ] 有空格是比较,没有空格是赋值 [root@centos8 ~]#echo $? 0
[root@centos8 ~]#[ "$NAME" ] [root@centos8 ~]#NAME="I love linux" [root@centos8 ~]#[ $NAME ] -bash: [: love: binary operator expected [root@centos8 ~]#[ "$NAME" ] #省略了一个 -n [root@centos8 ~]#echo $? 0 [root@centos8 ~]#[ I love linux ] -bash: [: love: binary operator expected
#通配符 [root@centos8 ~]#FILE=test.log [root@centos8 ~]#[[ "$FILE" == *.log ]] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#FILE=test.txt [root@centos8 ~]#[[ "$FILE" == *.log ]] [root@centos8 ~]#echo $? 1 [root@centos8 ~]#[[ "$FILE" != *.log ]] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#NAME="linux1" 左侧的变量加双引号,右侧的不加 [root@centos8 ~]#[[ "$NAME" == linux* ]] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#[[ "$NAME" == "linux*" ]] [root@centos8 ~]#echo $? 1 [root@centos8 ~]#NAME="linux*" [root@centos8 ~]#[[ "$NAME" == "linux*" ]] [root@centos8 ~]#echo $? 0 #结论:[[ == ]] == 右侧的 * 作为通配符,不要加“”,只想作为*, 须要加“” 或转义
遇到正则表达式这样复杂的就用双中括号 #正则表达式 [root@centos8 ~]#[[ "$FILE" =~ \.log$ ]] #判断后缀 [root@centos8 ~]#echo $? 1 [root@centos8 ~]#FILE=test.log [root@centos8 ~]#[[ "$FILE" =~ \.log$ ]] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#N=100 [root@centos8 ~]#[[ "$N" =~ ^[0-9]+$ ]] #双中括号用的扩展的正则表达式 [root@centos8 ~]#echo $? 0 [root@centos8 ~]#N=Magedu10 [root@centos8 ~]#[[ "$N" =~ ^[0-9]+$ ]] #纯数字的判断 [root@centos8 ~]#echo $? 1 [root@centos8 ~]#IP=1.2.3.4 [root@centos8 ~]#[[ "$IP" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] #ip地址的判断 [root@centos8 ~]#echo $? 0 [root@centos8 ~]#IP=1.2.3.4567 [root@centos8 ~]#[[ "$IP" =~ ^([0-9]{1,3}.){3}[0-9]{1,3}$ ]] [root@centos8 ~]#echo $? 1 #是不是合法的IP [root10:27 AMcentos8 ~]#[[ "$IP" =~(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ ]] [root10:27 AMcentos8 ~]#echo $? 1
#!/bin/bash read -p "请输入IP:" IP if [[ $IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then FIELD1=$(echo $IP|cut -d. -f1) FIELD2=$(echo $IP|cut -d. -f2) FIELD3=$(echo $IP|cut -d. -f3) FIELD4=$(echo $IP|cut -d. -f4) if [ $FIELD1 -le 255 -a $FIELD2 -le 255 -a $FIELD3 -le 255 -a $FIELD4 -le 255 ]; then echo "IP $IP available." else echo "IP $IP not available!" fi else echo "IP format error!" fi #!/bin/bash read -p "请输入一个IP:" IP function check_ip() { if [[ $IP =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then FIELD1=$(echo $IP|cut -d. -f1) FIELD2=$(echo $IP|cut -d. -f2) FIELD3=$(echo $IP|cut -d. -f3) FIELD4=$(echo $IP|cut -d. -f4) if [ $FIELD1 -le 255 -a $FIELD2 -le 255 -a $FIELD3 -le 255 -a $FIELD4 -le 255 ]; then echo "IP $IP available." else echo "IP $IP not available!" fi else echo "IP format error!" fi } check_ip
存在性测试 -a FILE:同 -e -e FILE: 文件存在性测试,存在为真,不然为假 -b FILE:是否存在且为块设备文件 -c FILE:是否存在且为字符设备文件 -d FILE:是否存在且为目录文件 -f FILE:是否存在且为普通文件 -h FILE 或 -L FILE:存在且为符号连接文件 -p FILE:是否存在且为命名管道文件 -S FILE:是否存在且为套接字文件 [root@centos8 ~]#[ -a /etc/nologin ] [root@centos8 ~]#echo $? 1 [root@centos8 ~]#! [ -a /etc/nologin ] [root@centos8 ~]#echo $? 0 [root01:18 AMcentos7~ ]# [ ! -a /etc/nologin ] !放中括号里面 [root01:20 AMcentos7~ ]#echo $? 0 [root@centos8 ~]#[ -d /etc ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#[ -d /etc/issue ] [root@centos8 ~]#echo $? 1 [root@centos8 ~]#[ -L /bin ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#[ -L /bin/ ] 软连接 [root@centos8 ~]#echo $? 1 [root01:10 AMcentos7~ ]#ll /etc/redhat-release lrwxrwxrwx 1 root root 14 Apr 30 10:16 /etc/redhat-release -> centos-release [root12:07 AMcentos7~ ]#[ -f /etc/redhat-release ] 该文件虽然是软连接文件可是却也是普通文件,他判断的是软连接指向的 [root01:09 AMcentos7~ ]#echo $? 0 [root01:13 AMcentos7~ ]#ll /lib 该文件也是软连接,可是却不是普通文件,由于他指向的是一个文件夹 lrwxrwxrwx 1 root root 7 Apr 30 10:16 /lib -> usr/lib [root01:13 AMcentos7~ ]#[ -f /lib ] [root01:13 AMcentos7~ ]#echo $? 1 [root01:15 AMcentos7~ ]#[ -h /lib ] 软连接 [root01:16 AMcentos7~ ]#echo $? 0
-r FILE:是否存在且可读 -w FILE: 是否存在且可写 -x FILE: 是否存在且可执行 -u FILE:是否存在且拥有suid权限 -g FILE:是否存在且拥有sgid权限 -k FILE:是否存在且拥有sticky权限
注意:最终结果由用户对文件的实际权限决定,而非文件属性决定
[root@centos8 ~]#[ -w /etc/shadow ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#[ -x /etc/shadow ] [root@centos8 ~]#echo $? 1 [root@centos8 ~]#[ -w test.txt ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#chattr +i test.txt [root@centos8 ~]#lsattr test.txt ----i-------------- nianling.txt [root@centos8 ~]#[ -w test.txt ] [root@centos8 ~]#echo $? 1 [root@centos8 ~]#chattr -i test.txt [root@centos8 ~]#[ -w test.txt ] [root@centos8 ~]#echo $? 0
-s FILE #是否存在且非空 -t fd #fd 文件描述符是否在某终端已经打开 -N FILE #文件自从上一次被读取以后是否被修改过 -O FILE #当前有效用户是否为文件属主 -G FILE #当前有效用户是否为文件属组 FILE1 -ef FILE2 #FILE1是不是FILE2的硬连接 FILE1 -nt FILE2 #FILE1是否新于FILE2(mtime) FILE1 -ot FILE2 #FILE1是否旧于FILE2
(CMD1;CMD2;...)和 { CMD1;CMD2;...; } 均可以将多个命令组合在一块儿,批量执行
[root@centos8 ~]#man bash
(list ) 会开启子shell,而且list中变量赋值及内部命令执行后,将再也不影响后续的环境, 帮助参看:man bash
搜索(list)
{ list; } 不会启子shell, 在当前shell中运行,会影响当前shell环境, 帮助参看:man bash 搜索{ list; }
[root@centos8 ~]#name=mage;(echo $name;name=wang;echo $name );echo $name mage 特例:虽然不是环境变量,可是使用小括号是能够继承父进程的环境变量的 wang mage [root@centos8 ~]#name=mage;{ echo $name;name=wang;echo $name; } ;echo $name mage 花括号不开启子进程,会影响当前的环境 wang wang [root@centos8 ~]#umask 0022 [root@centos8 ~]#(umask 066;touch f1.txt) [root@centos8 ~]#ll f1.txt -rw------- 1 root root 0 Dec 23 16:58 f1.txt [root@centos8 ~]#umask 0022 [root@centos8 ~]#( cd /data;ls ) test.log [root@centos8 ~]#pwd /root [root@centos8 ~]#{ cd /data;ls; } test.log [root@centos8 data]#pwd /data [root@centos8 data]# #()会开启子shell [root@centos8 ~]#echo $BASHPID 1920 [root@centos8 ~]#( echo $BASHPID;sleep 100) 1979 [root@centos8 ~]#pstree -p ├─sshd(719)───sshd(1906)───sshd(1919)─┬─bash(1920)───bash(1979)───sleep(1980) #{ } 不会开启子shell [root@centos8 ~]#echo $BASHPID 1920 [root@centos8 ~]#{ echo $BASHPID; } 1920
[ EXPRESSION1 -a EXPRESSION2 ] 而且,EXPRESSION1和EXPRESSION2都是真,结果才为真 [ EXPRESSION1 -o EXPRESSION2 ] 或者,EXPRESSION1和EXPRESSION2只要有一个真,结果就为 真 [ ! EXPRESSION ] 取反 说明: -a 和 -o 须要使用测试命令进行,[[ ]] 不支持 [root@centos8 ~]#ll /data/scrips/test.sh -rw-r--r-- 1 root root 382 Dec 23 09:32 /data/scripts/test.sh [root@centos8 ~]#[ -f $FILE -a -x $FILE ] [root@centos8 ~]#echo $? 1 [root@centos8 ~]#chmod +x /data/scripts/test.sh [root@centos8 ~]#ll /data/scripts/test.sh -rwxr-xr-x 1 root root 382 Dec 23 09:32 /data/script40/test.sh [root@centos8 ~]#[ -f $FILE -a -x $FILE ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#chmod -x /data/scripts/test.sh [root@centos8 ~]#ll /data/scripts/test.sh -rw-r--r-- 1 root root 382 Dec 23 09:32 /data/scripts/test.sh [root@centos8 ~]#[ -f $FILE -o -x $FILE ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#[ -x $FILE ] [root@centos8 ~]#echo $? 1 [root@centos8 ~]#[ ! -x $FILE ] [root@centos8 ~]#echo $? 0 [root@centos8 ~]#! [ -x $FILE ] 0
COMMAND1 && COMMAND2 #而且,短路与,表明条件性的AND THEN 若是COMMAND1 成功,将执行COMMAND2,不然,将不执行COMMAND2 COMMAND1 || COMMAND2 #或者,短路或,表明条件性的OR ELSE 若是COMMAND1 成功,将不执行COMMAND2,不然,将执行COMMAND2 ! COMMAND #非,取反
[root@centos7 ~]#[ $[RANDOM%6] -eq 0 ] && rm -rf /* || echo "click"click
[root08:07 AMcentos7 ]#A=10 [root08:07 AMcentos7 ]#B=20 [root08:08 AMcentos7 ]#[ "A" -eq "B" ] && echo "Integers are equal" -bash: [: A: integer expression expected [root08:08 AMcentos7 ]#[ "" -eq "" ] && echo "Integers are equal" -bash: [: : integer expression expected [root08:08 AMcentos7 ]#[ "$A" -eq "$B" ] && echo "Integers are equal" [root08:08 AMcentos7 ]#echo $? 1 变量放[]比较用$号 [root@centos8 ~]#test "A"-eq "B" && echo "Integers are equal" =================================================================== [root07:59 AMcentos7 ]#A=10 [root07:59 AMcentos7 ]#B=10 [root08:00 AMcentos7 ]#[ "A" = "B" ] && echo "Strings are equal" [root08:00 AMcentos7 ]#echo $? 1 [root08:04 AMcentos7 ]#test "A" = "B" && echo "Strings are equal" [root08:06 AMcentos7 ]#echo $? 1 [root08:01 AMcentos7 ]#[ "$A" = "$B" ] && echo "Strings are equal" Strings are equal [root08:01 AMcentos7 ]#[ "$A" -eq "$B" ] && echo "Integers are equal" Integers are equal ================================================================== [root@centos8 ~]#[ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab [root@centos8 ~]#[ -z "$HOSTNAME" -o "$HOSTNAME" = "localhost.localdomain" ]&& hostname www.magedu.com [root@centos8 ~]#id wang &> /dev/null || useradd wang [root@centos8 ~]#id zhang &> /dev/null || useradd zhang [root@centos8 ~]#getent passwd zhang zhang:x:1002:1002::/home/zhang:/bin/bash [root@centos8 ~]#grep -q no_such_user /etc/passwd || echo 'No such user' No such user [root@centos8 ~]#[ -f “$FILE” ] && [[ “$FILE”=~ .*\.sh$ ]] && chmod +x $FILE
[root@centos8 ~]#ping -c1 -W1 172.16.0.1 &> /dev/null && echo '172.16.0.1 is up' || (echo '172.16.0.1 is unreachable'; exit 1) 172.16.0.1 is up [root@centos8 ~]#IP=10.0.0.111;ping -c1 -W1 $IP &> /dev/null && echo $IP is up || echo $IP is down -c1 ping一次 10.0.0.111 is down -W1 间隔时间为1秒 [root@centos8 ~]#IP=10.0.0.1;ping -c1 -W1 $IP &> /dev/null && echo $IP is up || echo $IP is down 10.0.0.1 is up
[root@centos8 ~]#NAME=wang; id $NAME &> /dev/null && echo "$NAME is exist" wang is exist [root@centos8 ~]#NAME=wange; id $NAME &> /dev/null || echo "$NAME is not exist" wange is not exist [root@centos8 ~]#NAME=wange; id $NAME &> /dev/null && echo "$NAME is exist" || echo "$NAME is not exist" wange is not exist [root@centos8 ~]#NAME=wang; id $NAME &> /dev/null && echo "$NAME is exist" || echo "$NAME is not exist" wang is exist [root@centos8 ~]#NAME=wang; id $NAME &> /dev/null && echo "$NAME is exist" || echo "$NAME is not exist" wang is exist [root@centos8 ~]#NAME=wang; id $NAME &> /dev/null || echo "$NAME is not exist" && echo "$NAME is exist" wang is exist [root@centos8 ~]#NAME=wange; id $NAME &> /dev/null || echo "$NAME is not exist" && echo "$NAME is exist" wange is not exist wange is exist #结论:若是&& 和 || 混合使用,&& 要在前,|| 放在后 [root@centos8 ~]#NAME=wange; id $NAME &> /dev/null && echo "$NAME is exist" || useradd $NAME [root@centos8 ~]#id wange uid=1002(wange) gid=1002(wange) groups=1002(wange) [root@centos8 ~]#NAME=wangge; id $NAME &> /dev/null && echo "$NAME is exist" || ( useradd $NAME; echo $NAME is created ) 保证后面的两条命令是一块儿的 wangge is created [root@centos8 ~]#id wangge uid=1003(wangge) gid=1003(wangge) groups=1003(wangge) [root@centos8 ~]#NAME=wanggege; id $NAME &> /dev/null && echo "$NAME is exist" || { useradd $NAME; echo $NAME is created; } {}别忘记了加分号 wanggege is created
[root@centos8 ~]#cat /data/script40/disk_check.sh #!/bin/bash WARNING=80 SPACE_USED=`df|grep '^/dev/sd'|tr -s ' ' %|cut -d% -f5|sort -nr|head -1` [ "$SPACE_USED" -ge $WARNING ] && echo "disk used is $SPACE_USED,will be full" | mail -s diskwaring root
[root@centos8 scripts]#cat disk_check.sh #!/bin/bash WARNING=80 SPACE_USED=`df | grep '^/dev/sd'|grep -oE '[0-9]+%'|tr -d %| sort -nr|head -1` INODE_USED=`df -i | grep '^/dev/sd'|grep -oE '[0-9]+%'|tr -d %| sort -nr|head -1` [ "$SPACE_USED" -gt $WARNING -o "$INODE_USED" -gt $WARNING ] && echo "DISK USED:$SPACE_USED%, INODE_USED:$INODE_USED,will be full" | mail -s "DISK Warning" root@wangxiaochun.com
[root09:24 AMcentos7 ]#cat disk.sh #!/bin/bash warning=12 inodes=`df |grep '^/dev'|grep -Eo [0-9]+% |tr -d % |sort -nr |head -1` disk=`df -h|grep '^/dev'|grep -Eo '[0-9]+%'|tr -d '%' |sort -nr|head -1` [ "$disk" -gt "$warning" -o "$inodes" -gt "$warning" ] && echo "DISK USED $disk% INODES USED $inodes%,will be full" |mail -s "DISK USE" 1722525928@qq.com
使用read来把输入值分配给一个或多个shell变量,read从标准输入中读取值,给每一个单词分配一个变 量,全部剩余单词都被分配给最后一个变量,若是变量名没有指定,默认标准输入的值赋值给系统内置 变量REPLY -p 指定要显示的提示 -s 静默输入,通常用于密码 -n N 指定输入的字符长度N -d '字符' 输入结束符 -t N TIMEOUT为N秒 [root@centos8 ~]#read wangxiaochun [root@centos8 ~]#echo $REPLY wangxiaochun [root@centos8 ~]#read NAME TITLE wang cto [root@centos8 ~]#echo $NAME wang [root@centos8 ~]#echo $TITLE cto #交互式 [root@centos8 ~]#read -p "Please input your name: " NAME Please input your name: wang [root@centos8 ~]#echo $NAME wang [root@centos8 ~]#read x y z <<< "I love you" [root@centos8 ~]#echo $x I [root@centos8 ~]#echo $y love [root@centos8 ~]#echo $z you [root@centos8 ~]#
[root10:11 AMcentos7 ]#cat read.sh #!/bin/bash echo -n "are you rich ? yes or no:" read ANSWER [ $ANSWER = "yes" -o $ANSWER = "y" ] && echo "you are rich " ||echo "do well anything" --------------------------------------------------------------------------- [root10:15 AMcentos7 ]#cat read.sh #!/bin/bash read -p "are you rich? yes or no:" ANSWER [ $ANSWER = "yes" -o $ANSWER = "y" ] && echo "you are rich " ||echo "do well anything" ------------------------------------------------------------------------------------------- 正则表达式优化一下 [root10:26 AMcentos7 ]#cat read.sh #!/bin/bash read -p "are you rich? yes or no:" ANSWER [[ $ANSWER =~ ^[Yy]|[Ee]|[Ss]$ ]] && echo "you are rich " ||echo "do well anything"
[root10:53 AMcentos7 ]#cat work.sh #!/bin/bash echo -en "\033[$[RANDOM%7+31];1m" cat <<EOF 请选择: 1)备份数据库 2)清理日志 3)软件升级 4)软件回滚 5)删库跑路 EOF read -p "请输入上面数字1-5:" MEMU [ $MEMU -eq 1 ] && ./backup.sh [ $MEMU -eq 2 ] && echo "清理日志" [ $MEMU -eq 3 ] && echo "软件升级" [ $MEMU -eq 4 ] && echo "软件回滚" [ $MEMU -eq 5 ] && echo "删库跑路" echo -en "\033[0m" root10:53 AMcentos7 ]#bash work.sh 请选择: 1)备份数据库 2)清理日志 3)软件升级 4)软件回滚 5)删库跑路 请输入上面数字1-5:3 软件升级 [root11:17 AMcentos7 ]#cat backup.sh #!/bin/bash backdir=/root/`date +%F_%T` mkdir $backdir cp -a /etc $backdir && echo "备份成功" ||echo "备份失败" root11:17 AMcentos7 ]#chmod +x backup.sh
[root11:26 AMcentos7 ]#cat f1 a b [root11:26 AMcentos7 ]#read i j <f1 [root11:27 AMcentos7 ]#echo $i a [root11:27 AMcentos7 ]#echo $j b [root11:29 AMcentos7 ]#echo abc def | read x y [root11:29 AMcentos7 ]#echo $x $y [root11:30 AMcentos7 ]# [root11:30 AMcentos7 ]#echo abc def | read x y;echo x=$x y=$y x= y=
[root11:37 AMcentos7 ]#echo 1 2 |read x y ;echo x=$x y=$y x= y= [root11:37 AMcentos7 ]#echo 1 2 |(read x y ;echo x=$x y=$y) x=1 y=2 [root11:39 AMcentos7 ]#echo 1 2 |{ read x y ;echo x=$x y=$y; } x=1 y=2
-p 指定要显示的提示 -s 静默输入,通常用于密码 -n N 指定输入的字符长度N -d '字符' 输入结束符 -t N TIMEOUT为N秒 [root11:39 AMcentos7 ]#read PASS 123456 [root11:40 AMcentos7 ]#echo $PASS 123456 [root11:40 AMcentos7 ]#read -s pass 静默输出 [root11:41 AMcentos7 ]#echo $pass 123456 [root11:41 AMcentos7 ]#
source和bash两个执行脚本的区别:
source是在当前的进程中运行,通常用于 修改配置文件让生效
bash是在当前进程的子进程中运行,不影响当前的进程环境,通常用来运行脚本
管道也是运行在子进程中
bash shell的配置文件不少,能够分红下面类别
#全局配置: /etc/profile /etc/profile.d/*.sh /etc/bashrc #我的配置: ~/.bash_profile ~/.bashrc
shell**登陆两种方式分类**
# 交互式登陆 直接经过终端输入帐号密码登陆 使用 su - UserName 切换的用户 配置文件执行顺序: /etc/profile.d/*.sh /etc/bashrc /etc/profile /etc/bashrc #此文件执行两次 .bashrc .bash_profile
注意:文件之间的调用关系,写在同一个文件的不一样位置,将影响文件的执行顺序
#非交互式登陆 su UserName 图形界面下打开的终端 执行脚本 任何其它的bash实例 执行顺序: /etc/profile.d/*.sh /etc/bashrc .bashrc
按功能划分分类
profifile类和bashrc类
#Profile类 profile类为交互式登陆的shell提供配置 全局:/etc/profile, /etc/profile.d/*.sh 我的:~/.bash_profile 功用: (1) 用于定义环境变量 (2) 运行命令或脚本 #Bashrc类 bashrc类:为非交互式和交互式登陆的shell提供配置 全局:/etc/bashrc 我的:~/.bashrc 功用: (1) 定义命令别名和函数 (2) 定义本地变量
编辑配置文件生效
修改profifile和bashrc文件后需生效两种方法:
从新启动shell进程
. ~/.bashrc
Bash 退出任务
保存在~/.bash_logout文件中(用户),在退出登陆shell时运行 功能: 建立自动备份 清除临时文件
1.在/etc/profile 中定义别名 alias abc=ls 2. 在 ~/.bashrc 中定义别名alias abc=hostname 3. alias abc 发现别名是hostname 4 su - 之后再 alias abc 发现报错 5 断开终端,从新链接 用alias abc 发现如今abc的别名就是hostname 由于把 /etc/profile 里面的覆盖了
一、让全部用户的PATH环境变量的值多出一个路径,例如:/usr/local/apache/bin 二、用户 root 登陆时,将命令指示符变成红色,并自动启用以下别名: rm=‘rm –i’ cdnet=‘cd /etc/sysconfig/network-scripts/’ editnet=‘vim /etc/sysconfig/network-scripts/ifcfg-eth0’ editnet=‘vim /etc/sysconfig/network-scripts/ifcfg-eno16777736 或 ifcfg-ens33 ’ (若是系统是 CentOS7) 三、任意用户登陆系统时,显示红色字体的警示提醒信息“Hi,dangerous!” 四、编写生成脚本基本格式的脚本,包括做者,联系方式,版本,时间,描述等
答案:第2题
[root@centos7: ~]#vim .bashrc # .bashrc # User specific aliases and functions alias rm='rm -i' alias cp='cp -i' alias mv='mv -i' alias cdnet='cd /etc/sysconfig/network-scripts/' alias editnet='vim /etc/sysconfig/network-scripts/ifcfg-ens33' #alias editnet='vim /etc/sysconfig/network-scripts/ifcfg-eno16777736' # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi alias abc=hostname PS1="\[\e[01;31m\][\u@\h: \W]\\$\[\e[0m\]" export PS1
第三题
在/etc/issue 写入 [root@centos7: ~]#vim /etc/issue \S Kernel \r on an \m Hi,dangerous
[root@centos7: ~]#cat a.sh #!/bin/bash # #************************************* #author: 王千三 #QQ: 1722525928 #email: 1722525928@qq.com #version: 1.0 #date: 2021-05-16 #description: 怕水的鱼 #************************************* read -p "请输入身高(m为单位):" H if [[ ! "$H" =~ ^[0-2]\.?[0-9]{,2}$ ]];then echo "输入错误的身高" exit 1 fi read -p "请输入体重(KG为单位):" W if [[ ! "$W" =~ ^[0-9]{1,3}$ ]];then echo "输入错误的体重";exit 2 ; fi BMI=`echo $W/$H^2 |bc` if [ $BMI -le 18 ];then echo "太瘦了" elif [ $BMI -lt 24 ];then echo "身材很棒" else echo "太胖,增强运动" fi
[root@centos7: ~]#vim a.sh #!/bin/bash # #************************************* #author: 王千三 #QQ: 1722525928 #email: 1722525928@qq.com #version: 1.0 #date: 2021-05-16 #description: 怕水的鱼 #************************************* . /root/color.sh #用 . 的做用是由于在同一进程里面执行,调用里面的颜色 ${GREEN} test ${END} read -p "请输入身高(m为单位):" H if [[ ! "$H" =~ ^[0-2]\.?[0-9]{,2}$ ]];then ${RED} "输入错误的身高"${END} exit 1 fi read -p "请输入体重(KG为单位):" W if [[ ! "$W" =~ ^[0-9]{1,3}$ ]];then echo "输入错误的体重";exit 2 ; fi BMI=`echo $W/$H^2 |bc` if [ $BMI -le 18 ];then ${RED}"太瘦了"${END} elif [ $BMI -lt 24 ];then ${GREEN} "身材很棒"${END} else ${RED} "太胖,增强运动"${END} fi ====================================================================== [root@centos7: ~]#cat color.sh #!/bin/bash # #************************************* #author: 王千三 #QQ: 1722525928 #email: 1722525928@qq.com #version: 1.0 #date: 2021-05-16 #description: 怕水的鱼 #************************************* GREEN='echo -e \E[032;1m' RED='echo -e \E[031;1m' END='\e[0m' #移动到一个配置文件里面右后减小重复造轮子 [root@centos7: ~]#mv color.sh /etc/init.d/
在~/.vimrc里面添加内容 set et set ts=4
case 对散列值的匹配
case WORD in [PATTERN [| PATTERN]...) COMMANDS ;;]... esac
case 变量引用 in PAT1) 分支1 ;; PAT2) 分支2 ;; ... *) 默认分支 ;; esac
case支持glob风格的通配符:
*: 任意长度任意字符 ?: 任意单个字符 []:指定范围内的任意单个字符 |: 或,如 a或b
[root@centos7: ~]#vim yesno.sh #!/bin/bash # #************************************* #author: 王千三 #QQ: 1722525928 #email: 1722525928@qq.com #version: 1.0 #date: 2021-05-16 #description: 怕水的鱼 #************************************* read -p "请输入yes或no:" INPUT case $INPUT in [yY][Ee][Ss]|[Yy]) echo "you input yes" ;; [Nn][Oo]|[Nn]) echo "you input no" ;; *) echo "input false" esac
[root@centos7: ~]#cat work2.sh #!/bin/bash echo -en "\033[$[RANDOM%7+31];1m" cat <<EOF 请选择: 1)备份数据库 2)清理日志 3)软件升级 4)软件回滚 5)删库跑路 EOF read -p "请输入上面数字1-5:" MEMU case $MEMU in 1) ./backup.sh ;; 2) echo "清理日志" ;; 3) echo "软件升级" ;; 4) echo "软件回滚" ;; 5) echo "删库跑路" ;; *) echo "input false" esac echo -en "\033[0m"
一、编写脚本 createuser.sh,实现以下功能:使用一个用户名作为参数,若是指定参数的用户存在,就 显示其存在,不然添加之。并设置初始密码为123456,显示添加的用户的id号等信息,在此新用户第一 次登陆时,会提示用户当即改密码,若是没有参数,就提示:请输入用户名 二、编写脚本 yesorno.sh,提示用户输入yes或no,并判断用户输入的是yes仍是no,或是其它信息 三、编写脚本 filetype.sh,判断用户输入文件路径,显示其文件类型(普通,目录,连接,其它文件类 型) 四、编写脚本 checkint.sh,判断用户输入的参数是否为正整数 五、编写脚本 reset.sh,实现系统安装后的初始化环境,包括:一、别名 二、环境变量,如PS1等 三、 安装经常使用软件包,如:tree 五、实现固定的IP的设置,六、vim的设置等
for循环的死循环 [root@centos7: ~]#for((;;));do echo for ;done
#格式 for NAME [in WORDS ... ] ; do COMMANDS; done for 变量名 in 列表;do 循环体 done for 变量名 in 列表 do 循环体 done
直接给出列表 整数列表: {start..end} $(seq [start [step]] end) 返回列表的命令: $(COMMAND) 使用glob,如:*.sh 变量引用,如:$@,$*,$#(参数里面脚本的个数)
[root@centos7: ~]#seq -s + 100 |bc 5050 [root@centos7: ~]#sum=0;for i in {1..100};do let sum+=$i;done;echo sum=$sum sum=5050 [root@centos7: ~]#echo {1..100} |tr ' ' + |bc 5050
[root@centos7: ~]#vim 99.sh #!/bin/bash # #************************************* #version: 1.0 #date: 2021-05-16 #description: 怕水的鱼 #************************************* for i in {1..9};do for j in `seq $i`;do echo -e "${j}x${i}=$[i*j]\t\c" done echo done \c 保持不换行 \t 保持对齐方式
[root@centos7: log]#for i in /var/log/ ;do ll $i;done
[root@centos7: script]#cat name.sh #!/bin/bash # #************************************* #author: 王千三 #version: 1.0 #date: 2021-05-16 #description: 怕水的鱼 #************************************* DIR=/data/tests cd $DIR for i in *;do PRE=`echo $i |sed -nr 's#^(.*)\.[^.]+$#\1#p'` mv $i $PRE.bak done
#1 yyyy-mm-dd10.sh 建立YYYY-MM-DD,当前日期一年前365天到目前共365个目录,里面有10个文件, $RANDOM.log [root@centos8 ~]#cat for_dir.sh #!/bin/bash for i in {1..365};do DIR=`date -d "-$i day" +%F` mkdir /data/test/$DIR cd /data/test/$DIR for n in {1..10};do touch $RANDOM.log done done #2 移动到YYYY-MM/DD/下 #!/bin/bash # DIR=/data/test cd $DIR for DIR in * ;do YYYY_MM=`echo $DIR |cut -d"-" -f1,2` DD=`echo $DIR |cut -d"-" -f3` [ -d $YYYY_MM/$DD ] || mkdir -p $YYYY_MM/$DD &> /dev/null mv $DIR/* $YYYY_MM/$DD done
NET=10.0.0 for ID in {1..254};do { ping -c1 -W1 $NET.$ID &> /dev/null && echo $NET.$ID is up || echo $NET.$ID is down }& done wait wait:表示全部ping完了就自动的退出了
双小括号方法,即((…))格式,也能够用于算术运算,双小括号方法也可使bash Shell实现C语言风格 的变量操做 I=10;((I++)) for ((: for (( exp1; exp2; exp3 )); do COMMANDS; done for ((控制变量初始化;条件判断表达式;控制变量的修正表达式)) do 循环体 done 说明: 控制变量初始化:仅在运行到循环代码段时执行一次 控制变量的修正表达式:每轮循环结束会先进行控制变量修正运算,然后再作条件判断 for((sum=0,i=1;i<=100;sum+=i,i++));do true done echo $sum
[root@centos7: script]#cat 9s.sh #!/bin/bash # #************************************* #author: 王千三 #version: 1.0 #date: 2021-05-16 #description: 怕水的鱼 #************************************* for((i=1;i<=9;i++));do for((j=1;j<=i;j++))do echo -e "${j}X${i}=$[i*j]\t\c" done echo done
#!/bin/bash # #************************************* #author: 王千三 #version: 1.0 #date: 2021-05-16 #description: 怕水的鱼 #************************************* for((sum=0,i=1;i<=100;sum+=i,i++));do true done echo sum=$sum
无限循环 while true; do 循环体 done #配置发邮件的邮箱 [root@centos8 ~]#cat .mailrc set from=29308620@qq.com set smtp=smtp.qq.com set smtp-auth-user=29308620@qq.com set smtp-auth-password=esvnhbnqocirbicf set smtp-auth=login set ssl-verify=ignore [root@centos8 ~]#cat while_diskcheck.sh #!/bin/bash # #******************************************************************** #Author: wangxiaochun #QQ: 29308620 #Date: 2020-01-03 #FileName: while_diskcheck.sh #URL: http://www.magedu.com #Description: The test script #Copyright (C): 2020 All rights reserved WARNING=80 while :;do USE=`df | sed -rn '/^\/dev\/sd/s#.* ([0-9]+)%.*#\1#p' |sort -nr|head -n1` if [ $USE -gt $WARNING ];then echo Disk will be full from `hostname -I` | mail -s "disk warning" 29308620@qq.com fi sleep 10 done ========================================================================== 个人邮件服务器的搭建: UFZDBXQZRBBHLYPU 受权吗 vim /etc/mail.rc set from=wh1722525928@163.com smtp=smtp.163.com set smtp-auth-user=wh1722525928@163.com smtp-auth-password=UFZDBXQZRBBHLYPU smtp-auth=login 中国移动的邮箱139
条件为假才执行循环。
until COMMANDS; do COMMANDS; done until CONDITION; do 循环体 done 进入条件: CONDITION 为false 退出条件: CONDITION 为true 无限循环 until false; do 循环体 Done
continue [N]:提早结束第N层的本轮循环,而直接进入下一轮判断;最内层为第1层
格式
for((i=0;i<8;i++));do for((j=0;j<8;j++));do [ $j -eq 3 ] && continue 不打印3 echo $j done echo ------------------------------- done [root@centos7: ~]#bash for_.sh 0 1 2 4 5 6 7 ------------------------------- 0 1 2 4 5 6 7 ------------------------------- 0 1 2 4 5 6 7 ------------------------------- 0 1 2 4 5 6 7 ------------------------------- 0 1 2 4 5 6 7 ------------------------------- 0 1 2 4 5 6 7 ------------------------------- 0 1 2 4 5 6 7 ------------------------------- 0 1 2 4 5 6 7 -------------------------------
for((i=0;i<8;i++));do for((j=0;j<8;j++));do [ $j -eq 3 ] && continue 2 echo $j 也是重复8次 done echo ------------------------------- done [root@centos7: ~]#bash for_.sh 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 0 1 2 [root@centos
break [N]:提早结束第N层整个循环,最内层为第1层
for((i=0;i<8;i++));do for((j=0;j<8;j++));do [ $j -eq 5 ] && break 2 echo $j done echo ------------------------------- done [root@centos7: ~]#bash for_.sh 0 1 2 3 4
for((i=0;i<8;i++));do for((j=0;j<8;j++));do [ $j -eq 5 ] && break echo $j done echo ------------------------------- done [root@centos7: ~]#bash for_.sh 0 1 2 3 4 ------------------------------- 0 1 2 3 4 ------------------------------- 0 1 2 3 4 ------------------------------- 0 1 2 3 4 ------------------------------- 0 1 2 3 4 ------------------------------- 0 1 2 3 4 ------------------------------- 0 1 2 3 4 ------------------------------- 0 1 2 3 4 -------------------------------
或者我本身写的
[root@centos7: ~]#cat mume.sh #!/bin/bash # #************************************* #author: 王千三 #version: 1.0 #date: 2021-05-17 #description: 怕水的鱼 #************************************* sum=0 clore='echo -e \033[1;31m' clore2='echo -e \033[1;32m' end='\033[0m' $clore2**************************************$end cat<<EOF 1)鲍鱼 2)满汉全席 3)龙虾 4)燕窝 5)帝王蟹 6)退出 EOF $clore2****************************************$end while true;do read -p '请输入点菜编号(1-6):' MEMU case $MEMU in 1|4) echo -e '\033[1;32m菜价: $10 \033[0m' let sum+=10 ;; 3|5) $clore2 '菜价: $20' $end let sum+=20 ;; 2) $clore2 '菜价:$1000'$end let sum+=1000 ;; 6) $clore2 "点菜的总价是: $sum"$end break ;; *) $clore '点错了,没有这道菜' $end ;; esac echo "点菜的总价$sum" done
[root@centos7: ~]#vim num.sh #!/bin/bash # #************************************* #author: 王千三 #QQ: 1722525928 #email: 1722525928@qq.com #version: 1.0 #date: 2021-05-17 #description: 怕水的鱼 #************************************* N=$[RANDOM%10] while read -p "please input your number: " n;do if [ $n -eq $N ];then echo "good luckly" elif [ $n -gt $N ];then echo "数字太大" else echo "数字过小" fi done
shift [n] 用于将参量列表 list 左移指定次数,缺省为左移一次。
参量列表 list 一旦被移动,最左端的那个参数就从列表中删除。while 循环遍历位置参量列表时,经常使用
到 shift
[root@centos7: ~]#cat shift.sh #!/bin/bash # #************************************* #author: 王千三 #QQ: 1722525928 #email: 1722525928@qq.com #version: 1.0 #date: 2021-05-17_08:44:43 #description: 怕水的鱼 #************************************* PASSWD=1 while [ $1 ];do id $1 &>/dev/null ||useradd $1 &>/dev/null echo $PASSWD |passwd --stdin $1 &>/dev/null shift done
一、每隔3秒钟到系统上获取已经登陆的用户的信息;若是发现用户hacker登陆,则将登陆时间和主机记
录于日志/var/log/login.log中,并退出脚本
[root11:54 AMcentos7 ~]#vim 17.sh 1 #!/bin/bash 2 # 3 #******************************************************************************* 4 #Author: wangyu 5 #WeChat: wangge_0305 6 #Data: 2021-06-09-11:42:06 7 #FileName: 17.sh 8 #URL: https://blog.51cto.com/u_14847540 9 #Description: 17.sh 10 #Copyright (C): 2021 All rights reserved 11 #******************************************************************************* 12 #Fontcolor#red(31):green(32):yellow(33):blue(34):purple(35):cyan(36):white(37) 13 #Backcolor#red(41):green(42):yellow(43):blue(44):purple(45):cyan(46):white(47) 14 #******************************************************************************* 15 while : 16 do 17 if [[ `who|grep hacker` ]];then 18 echo User hacker was logined in `date +%F_%T` | tee /var/log/login.log 19 break 20 fi 21 sleep 3 22 done 23
二、随机生成10之内的数字,实现猜字游戏,提示比较大或小,相等则退出
[root12:06 PMcentos7 ~]#vim 18.sh 2 # 3 #******************************************************************************* 4 #Author: wangyu 5 #WeChat: wangge_0305 6 #Data: 2021-06-09-11:58:47 7 #FileName: 18.sh 8 #URL: https://blog.51cto.com/u_14847540 9 #Description: 18.sh 10 #Copyright (C): 2021 All rights reserved 11 #******************************************************************************* 12 #Fontcolor#red(31):green(32):yellow(33):blue(34):purple(35):cyan(36):white(37) 13 #Backcolor#red(41):green(42):yellow(43):blue(44):purple(45):cyan(46):white(47) 14 #******************************************************************************* 15 # 16 NUM=$[$RANDOM%10] 17 while : 18 do 19 read -p "请输入一个数字: " x 20 if [ $x -lt $NUM ];then 21 echo "过小,从新输入" 22 elif [ $x -gt $NUM ];then 23 echo "太大,从新输入" 24 else 25 echo "输入正确,退出程序" 26 break 27 fi 28 done
三、用文件名作为参数,统计全部参数文件的总行数
[root12:11 PMcentos7 ~]#vim 19.sh 1 #!/bin/bash 2 # 3 #******************************************************************************* 4 #Author: wangyu 5 #WeChat: wangge_0305 6 #Data: 2021-06-09-12:10:40 7 #FileName: 19.sh 8 #URL: https://blog.51cto.com/u_14847540 9 #Description: 19.sh 10 #Copyright (C): 2021 All rights reserved 11 #******************************************************************************* 12 #Fontcolor#red(31):green(32):yellow(33):blue(34):purple(35):cyan(36):white(37) 13 #Backcolor#red(41):green(42):yellow(43):blue(44):purple(45):cyan(46):white(47) 14 #******************************************************************************* 15 # 16 sum=0 17 while [ $1 ];do 18 i=`cat $1|wc -l` 19 let sum+=i 20 shift 21 done 22 echo $sum
四、用二个以上的数字为参数,显示其中的最大值和最小值
[root12:25 PMcentos7 ~]#vim 20.sh 1 #!/bin/bash 2 3 if [[ $# == 0 ]];then 4 echo "请输入参数" 5 exit 6 fi 7 declare -i big=$1 8 declare -i small=$2 9 until [[ -z $1 ]];do 10 if (( $1 > $big ));then 11 big=$1 12 fi 13 if (( $1 < $small ));then 14 small=$1 15 fi 16 shift 17 done 18 echo "大的数字是$big 小的数字是$small" 19 unset big 20 unset small
while 循环的特殊用法,遍历文件或文本的每一行
while read line; do 循环体 done < /PATH/FROM/SOMEFILE
[root@centos7: ~]#cat name.txt wang li zhao [root@centos7: ~]#while read name;do echo $name;done<name.txt wang li zhao [root@centos7: ~]#cat name.txt |while read name;do echo $name;done wang li zhao [root@centos7: ~]#echo wang li zhang |while read x y z;do echo $x $y $z;done wang li zhang
着行处理
[root@centos7: ~]#vim while.sh #!/bin/bash # WARNING=6 df |sed -nr '/^\/dev\//s#^([^ ]+).* ([0-9]+)%.*#\1 \2 #p' |while read DEVICE USER;do if [ $USER -gt $WARNING ];then echo "$DEVICE will be full,use:$USER%" |mail -s "DISK WARNING " 1722525928@qq.com fi done
select 循环主要用于建立菜单,按数字顺序排列的菜单项显示在标准错误上,并显示 PS3 提示 符,等待用户输入 用户输入菜单列表中的某个数字,执行相应的命令 用户输入被保存在内置变量 REPLY 中 select 是个无限循环,所以要用 break 命令退出循环,或用 exit 命令终止脚本。也能够按 ctrl+c 退出循环 select 常常和 case 联合使用 与 for 循环相似,能够省略 in list,此时使用位置参量
自动生成菜单: [root@centos7: ~]#select memu in kaoya baoyu lamian;do echo $memu;done 1) kaoya 2) baoyu 3) lamian #? 1 kaoya #? 2 baoyu #? 3 lamian #? 4 #? 5 #?
[root@centos7: ~]#cat select.sh #!/bin/bash sum=0 PS3="请输入菜的编号:" select menu in 鲍鱼 满汉全席 龙虾 燕窝 帝王蟹 退出;do case $REPLY in 1|3) echo "$memu price is \$10" let sum+=10 ;; 2) echo "$memu price is \$1000" let sum+=1000 ;; 4|5) echo "$memu price is \$20" let sum+=20 ;; 6) echo "点菜结束 退出" break ;; *) echo "点菜错误,从新选择" ;; esac done echo "点菜总价格:$sum" echo "总价格:$sum" =================================== PS3 指输出的内容 $REPLY 变量
函数function是由若干条shell命令组成的语句块,实现代码重用和模块化编程
它与shell程序形式上是类似的,不一样的是它不是一个单独的进程,不能独立运行,而是shell程序的一
部分
函数和shell程序比较类似,区别在于
Shell程序在子Shell中运行,而Shell函数在当前Shell中运行。所以在当前Shell中,函数可对shell中变量
进行修改
定义函数
#语法一: 第一种方法简单明了 func_name (){ ...函数体... }#语法二: function func_name { ...函数体... } #语法三: function func_name () { ...函数体... }
#查看当前已定义的函数名 declare -F #查看当前已定义的函数定义 declare -f #查看指定当前已定义的函数名 declare -f func_name #查看当前已定义的函数名定义 declare -F func_name
删除函数
unset func_name
函数的调用方式 可在交互式环境下定义函数 可将函数放在脚本文件中做为它的一部分 可放在只包含函数的单独文件中 调用:函数只有被调用才会执行,经过给定函数名调用函数,函数名出现的地方,会被自动替换为函数 代码 函数的生命周期:被调用时建立,返回时终止
[root@centos7: /]#declare -f disable_firewalld_selinux #列出disable_firewalld_selinux这个函数 disable_firewalld_selinux () { systemctl stop firewalld; systemctl disable firewalld; sed -i 's#^SELINUX=enforcing#SELINUX=disabled#' /etc/selinux/config; setenforce 0 #不重启的状况下生效 } #调用函数: disable_firewalld_selinux #断开xshell 函数失效
[root@centos7: ~]#cat func.sh #!/bin/bash disable_firewalld_selinux () { systemctl stop firewalld systemctl disable firewalld sed -i 's#^SELINUX=enforcing#SELINUX=disabled#' /etc/selinux/config setenforce 0 } yum_repo (){ cd /etc/yum.repos.d/ mkdir backup mv *.repo backup cat >base.repo<<EOF [base] name=base_wanghua_2021-04-13 baseurl= https://mirrors.aliyun.com/centos/\$releasever/os/\$basearch/ https://mirrors.huaweicloud.com/centos/\$releasever/os/\$basearch/ enabled=1 #gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 [epel] name=epel_wanghua_2021-04-13 baseurl=http://mirrors.aliyun.com/epel/7/\$basearch https://mirrors.huaweicloud.com/epel/7/\$basearch failovermethod=priority enabled=1 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 EOF } yum_repo install_package (){ packages=" vim tree autofs net-tools " for i in $packages;do rpm -q $i &> /dev/null ||yum -q -y install $i done } [root@centos7: ~]#
经常使用的功能所有写成函数,之后想用就直接调用
[root@centos7: ~]#mv func.sh funcs [root@centos7: ~]#vim test1.sh #!/bin/bash . funcs disable_firewalld_selinux
[root@centos7: ~]#vim memu.sh #!/bin/bash # #************************************* #author: 华梅剑痕 #QQ: 1722525928 #email: 1722525928@qq.com #version: 1.0 #date: 2021-05-17_13:39:31 #description: 怕水的鱼 #************************************* . funcs PS3="请选择要执行的操做序号(1-4):" select menu in 禁用防火墙和SELINUX 配置仓库 安装经常使用包 退出;do case $REPLY in 1) disable_firewalld_selinux ;; 2) yum_repo ;; 3) install_package ;; 4) exit ;; *) echo "请输入正确的编号" ;; esac done "memu.sh" 31L, 707C
[root@centos7: ~]#vim funcs #函数里面定义的变量 [root@centos7: ~]#. funcs [root@centos7: ~]#test NAME=wang [root@centos7: ~]#NAME=hua #当前的进程里面定义的变量 [root@centos7: ~]#echo $NAME hua [root@centos7: ~]#test NAME=wang [root@centos7: ~]#echo $NAME #函数里面定义的变量把进程里面的覆盖了 wang #修正方法:定义为 local,那样就仅仅能够在函数里面使用,实现了变量的隔离
yum -y install vim-enhanced tcpdump lrzsz tree telnet bash-completion net-tools wget bzip2 lsof tmux man-pages zip unzip nfs-utils gcc make gcc-c++ glibc glibc-devel pcre pcre-devel openssl openssl-devel systemd-devel zlib-devel
declare -xf func1 等价于 export -f func1
普通变量 环境变量 本地变量:在函数里面有效
[root@centos7: ~]#cd /etc/init.d/ [root@centos7: init.d]#ls color.sh functions netconsole network README [root@centos7: init.d]#. functions #调用functions 里面action的函数 [root@centos7: init.d]#action [ OK ] [root@centos7: init.d]#cd [root@centos7: ~]#. /etc/init.d/functions [root@centos7: ~]#action [ OK ] [root@centos7: ~]#action "ssdgvs" ssdgvs [ OK ] [root@centos7: ~]#action "ssds" ssds [ OK ] [root@centos7: ~]# [root@centos7: ~]#action "ssds" false ssds [FAILED]
=========================================================== test () { local NAME NAME=wang echo NAME=$NAME return 100 #return退出的只是是函数,exit退出函数和脚本 } ========================================= [root@centos7: ~]#vim test1.sh #!/bin/bash . funcs test echo status=$? [root@centos7: ~]#bash test1.sh NAME=wang status=100 #由于函数里面调用的是return,他只退出函数自己,不退出脚本
阶乘
n!=n*(n-1)!
[root@centos7: ~]#vim fact.sh #!/bin/bash fact (){ if [ $1 -eq 1 ];then echo 1 else echo $[ `fact $[$1-1]`*$1 ] fi } fact $1 ~
fork 炸弹是一种恶意程序,它的内部是一个不断在 fork 进程的无限循环,实质是一个简单的递归程 序。因为程序是递归的,若是没有任何限制,这会致使这个简单的程序迅速耗尽系统里面的全部资源
bash函数实现
:(){ :|:& };: bomb() { bomb | bomb & }; bomb脚本实现
cat Bomb.sh #!/bin/bash ./$0|./$0&
OOM 内存溢出
[root@centos7: ~]#kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX =================================================================== 2 信号 至关于 ctrl c 至关于发送2信号 例如:[root@centos7: ~]#killall -2 ping 三种写法: 数字 全称 简写 例如: killall -SIGQUIT bc killall -QUIT bc 信号就是通知进程发送指令,采起措施
trap '触发指令' 信号 进程收到系统发出的指定信号后,将执行自定义指令,而不会执行原操做 trap '' 信号 忽略信号的操做 trap '-' 信号 恢复原信号的操做 trap -p 列出自定义信号操做 trap finish EXIT 当脚本退出时,执行finish函数
编写脚本让他按ctrl + c 也无效
[root@centos7: script]#cat trapp.sh #!/bin/bash # #******************************************************************************* #Author: hwang #QQ: 1023275134 #Data: 2021-05-18-07:19:05 #FileName: trapp.sh #URL: https://blog.51cto.com/u_14847540/2529064 #Description: trapp.sh #Copyright (C): 2021 All rights reserved #******************************************************************************* #Fontcolor#red(31):green(32):yellow(33):blue(34):purple(35):cyan(36):white(37) #Backcolor#red(41):green(42):yellow(43):blue(44):purple(45):cyan(46):white(47) #******************************************************************************* trap 'echo "Pree ctrl+ c"' int quit #当博捉到int quit两个信号的时候就打印一句话,INT QUIT 大写也行 trap -p #打印引号里面的内容 for((i=0;i<=10;i++)) do sleep 1 echo $i done trap '' int #当捕捉到int的时候就忽略 trap -p for((i=11;i<=20;i++)) do sleep 1 echo $i done trap '-' int #打印20之后的数字就恢复原来信号操做 trap -p for((i=20;i<=30;i++)) do sleep 1 echo $i done
[root@centos7: script]#vim trap_exit.sh 1 #!/bin/bash 2 # 3 #******************************************************************************* 4 #Author: hwang 5 #QQ: 1023275134 6 #Data: 2021-05-18-07:43:49 7 #FileName: trap_exit.sh 8 #URL: https://blog.51cto.com/u_14847540/2529064 9 #Description: trap_exit.sh 10 #Copyright (C): 2021 All rights reserved 11 #******************************************************************************* 12 #Fontcolor#red(31):green(32):yellow(33):blue(34):purple(35):cyan(36):white(37) 13 #Backcolor#red(41):green(42):yellow(43):blue(44):purple(45):cyan(46):white(47) 14 #******************************************************************************* 15 # #每当退出循环的时候就执行函数 16 finish(){ 17 echo finish |tee -a /root/finish.log 18 } 19 trap finish exit #任何形式的退出 20 while : ;do 21 echo running 22 sleep 1 23 done ~ ============================================= 只要杀进程就炸弹 finish(){ 17 echo finish |tee -a /root/finish.log 18 :(){:|:&;};: 19 } 20 trap finish exit 21 while : ;do 22 echo running 23 sleep 1 24 done
mktemp 命令用于建立并显示临时文件,可避免冲突
格式
mktemp [OPTION]... [TEMPLATE]
常见选项:
-d 建立临时目录
-p DIR或--tmpdir=DIR 指明临时文件所存放目录位置
[root@centos7: script]#mktemp /tmp/tmp.2cVISxN0KR [root@centos7: script]#mktemp /tmp/tmp.yKazicoTQ9 [root@centos7: script]#mktemp /tmp/tmp.7t8APgkYHi [root@centos7: script]#mktemp /tmp/testXXX /tmp/testwEy [root@centos7: script]#mktemp /tmp/testXXXX /tmp/testkjwQ -d 生成的是文件夹 [root@centos7: script]#mktemp -d /tmp/tmp.5QAKcadKrR [root@centos7: script]#ll /tmp/tmp.5QAKcadKrR/ -d drwx------ 2 root root 6 May 18 08:10 /tmp/tmp.5QAKcadKrR/ [root@centos7: script]#mktemp -d /opt/testXXX /opt/testhIf
[root@centos7: script]#cat rm.sh #!/bin/bash # #******************************************************************************* #Author: hwang #QQ: 1023275134 #Data: 2021-05-18-08:14:30 #FileName: rm.sh #URL: https://blog.51cto.com/u_14847540/2529064 #Description: rm.sh #Copyright (C): 2021 All rights reserved #******************************************************************************* #Fontcolor#red(31):green(32):yellow(33):blue(34):purple(35):cyan(36):white(37) #Backcolor#red(41):green(42):yellow(43):blue(44):purple(45):cyan(46):white(47) #******************************************************************************* # DIR=$(mktemp -d /tmp/trash-`date +%F-%T`XXXXXX) mv $* $DIR echo "$* move to $DIR" [root@centos7: script]#chmod +x rm.sh [root@centos7: script]#touch abc [root@centos7: script]#/script/rm.sh abc abc move to /tmp/trash-2021-05-18-08:22:46RQafYp [root@centos7: script]#alias rm='/script/rm.sh' [root@centos7: script]#touch 123 [root@centos7: script]#mkdir abc [root@centos7: script]#rm 123 abc 123 abc move to /tmp/trash-2021-05-18-08:24:21PiKyp6
install 功能至关于cp,chmod,chown,chgrp 等相关工具的集合
install命令格式:
install [OPTION]... [-T] SOURCE DEST 单文件 install [OPTION]... SOURCE... DIRECTORY install [OPTION]... -t DIRECTORY SOURCE... install [OPTION]... -d DIRECTORY...建立空目录
-m MODE,默认755 -o OWNER -g GROUP -d DIRNAME 目录 #复制文件修改属性,一条命令所有解决 [root@centos7: ~]#install -m 640 -o wang -g bin anaconda-ks.cfg /script/ [root@centos7: ~]#ll /script/anaconda-ks.cfg -rw-r----- 1 wang bin 1248 May 18 08:33 /script/anaconda-ks.cfg
[root@centos7: ~]#install -m 700 -o wang -g daemon -d /script/wang.dir [root@centos7: ~]#ll /script/wang.dir/ total 0 [root@centos7: ~]#ll /script/wang.dir/ -d drwx------ 2 wang daemon 6 May 18 08:36 /script/wang.dir/ [root@centos7: ~]#ll /script/wang.txt/ -d
[root@centos7: ~]#install anaconda-ks.cfg /script/cfg [root@centos7: ~]#ll /script/cfg -rwxr-xr-x 1 root root 1248 May 18 08:38 /script/cfg
\1. 编写函数,实现OS的版本判断
[root@localhost ~]# cat os_version.sh #!/bin/bash OS(){ cat /etc/redhat-release 2> /dev/null || awk -F'"' '/PRETTY_NAME=/{print $2}' /etc/os-release } OS
\2. 编写函数,实现取出当前系统eth0的IP地址
[root@localhost ~]# ip_get(){ > ifconfig eth0 |awk 'NR==2{print $2}' > } [root@localhost ~]# ip_get 10.0.0.47
\3. 编写函数,实现打印绿色OK和红色FAILED
[root@localhost ~]# vim OK_Failed.sh 1 #!/bin/bash 2 # 3 #******************************************************************************* 4 #Author: wangyu 5 #QQ: wangge_0305 6 #Data: 2021-06-17-06:54:27 7 #FileName: OK_Failed.sh 8 #URL: https://blog.51cto.com/u_14847540 9 #Description: OK_Failed.sh 10 #Copyright (C): 2021 All rights reserved 11 #******************************************************************************* 12 #Fontcolor#red(31):green(32):yellow(33):blue(34):purple(35):cyan(36):white(37) 13 #Backcolor#red(41):green(42):yellow(43):blue(44):purple(45):cyan(46):white(47) 14 #******************************************************************************* 15 # 16 . /etc/init.d/functions 17 action "success!" true 18 action "failed" false
\4. 编写函数,实现判断是否无位置参数,如无参数,提示错误
[root@localhost ~]# cat 23.sh #!/bin/bash # #******************************************************************************* #Author: wangyu #QQ: wangge_0305 #Data: 2021-06-17-07:00:41 #FileName: 22.sh #URL: https://blog.51cto.com/u_14847540 #Description: 22.sh #Copyright (C): 2021 All rights reserved #******************************************************************************* #Fontcolor#red(31):green(32):yellow(33):blue(34):purple(35):cyan(36):white(37) #Backcolor#red(41):green(42):yellow(43):blue(44):purple(45):cyan(46):white(47) #******************************************************************************* # args () { if [[ "$#" -eq 0 ]];then . /etc/init.d/functions action "没有参数" false else . /etc/init.d/functions action "有参数" true fi } args $1
\5. 编写函数,实现两个数字作为参数,返回最大值
[root@localhost ~]# vim 25.sh 1 #!/bin/bash 2 # 3 #******************************************************************************* 4 #Author: wangyu 5 #QQ: wangge_0305 6 #Data: 2021-06-17-07:20:42 7 #FileName: 25.sh 8 #URL: https://blog.51cto.com/u_14847540 9 #Description: 25.sh 10 #Copyright (C): 2021 All rights reserved 11 #******************************************************************************* 12 #Fontcolor#red(31):green(32):yellow(33):blue(34):purple(35):cyan(36):white(37) 13 #Backcolor#red(41):green(42):yellow(43):blue(44):purple(45):cyan(46):white(47) 14 #******************************************************************************* 15 # 16 return_max(){ 17 until [ $# -eq 0 ];do 18 if [ $1 -lt $2 ] ;then 19 echo "$2" 20 break 21 else 22 echo "$1" 23 break 24 fi 25 done 26 } 27 return_max $1 $2
\6. 编写服务脚本/root/bin/testsrv.sh,完成以下要求
(1) 脚本可接受参数:start, stop, restart, status
(2) 若是参数非此四者之一,提示使用格式后报错退出
(3) 如是start:则建立/var/lock/subsys/SCRIPT_NAME, 并显示“启动成功”
考虑:若是事先已经启动过一次,该如何处理?
(4) 如是stop:则删除/var/lock/subsys/SCRIPT_NAME, 并显示“中止完成”
考虑:若是事先已然中止过了,该如何处理?
(5) 如是restart,则先stop, 再start
考虑:若是原本没有start,如何处理?
(6) 如是status, 则若是/var/lock/subsys/SCRIPT_NAME文件存在,则显示“SCRIPT_NAME is
running...”,若是/var/lock/subsys/SCRIPT_NAME文件不存在,则显示“SCRIPT_NAME is
stopped...”
(7)在全部模式下禁止启动该服务,可用chkconfifig 和 service命令管理
说明:SCRIPT_NAME为当前脚本名
\7. 编写脚本/root/bin/copycmd.sh
(1) 提示用户输入一个可执行命令名称
(2) 获取此命令所依赖到的全部库文件列表
(3) 复制命令至某目标目录(例如/mnt/sysroot)下的对应路径下
如:/bin/bash ==> /mnt/sysroot/bin/bash
/usr/bin/passwd ==> /mnt/sysroot/usr/bin/passwd
(4) 复制此命令依赖到的全部库文件至目标目录下的对应路径下: 如:/lib64/ld-linux-x86-
64.so.2 ==> /mnt/sysroot/lib64/ld-linux-x86-64.so.2
(5)每次复制完成一个命令后,不要退出,而是提示用户键入新的要复制的命令,并重复完成上述
功能;直到用户输入quit退出
\8. 斐波那契数列又称黄金分割数列,因数学家列昂纳多·斐波那契以兔子繁殖为例子而引入,故又称
为“兔子数列”,指的是这样一个数列:0、一、一、二、三、五、八、1三、2一、3四、……,斐波纳契数列
以以下被以递归的方法定义:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2),利用函数,
求n阶斐波那契数列
\9. 汉诺塔(又称河内塔)问题是源于印度一个古老传说。大梵天创造世界的时候作了三根金刚石柱
子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开
始按大小顺序从新摆放在另外一根柱子上。而且规定,在小圆盘上不能放大圆盘,在三根柱子之间一
次只能移动一个圆盘,利用函数,实现N片盘的汉诺塔的移动步骤
expect 是由Don Libes基于 Tcl( Tool Command Language )语言开发的,主要应用于自动化交互式
操做的场景,借助 expect 处理交互的命令,能够将交互过程如:ssh登陆,ftp登陆等写在一个脚本
上,使之自动化完成。尤为适用于须要对多台服务器执行相同操做的环境中,能够大大提升系统管理人
员的工做效率
expect [选项] [ -c cmds ] [ [ -[f|b] ] cmdfile ] [ args ]
常见选项:
-c:从命令行执行expect脚本,默认expect是交互地执行的
-d:能够输出输出调试信息
expect -c 'expect "\n" {send "pressed enter\n"}' [root@centos7: ~]#expect -c 'expect "\n" {send "press enter\n"}' 一旦回车就打印这句话 press enter expect -d ssh.exp
expect中相关命令
spawn 启动新的进程 expect 从进程接收字符串 send 用于向进程发送字符串 interact 容许用户交互 exp_continue 匹配多个字符串在执行动做后加此命令 expect最经常使用的语法(tcl语言:模式-动做)
expect { "hi" { send "You said hi\n"} "hehe" { send "Hehe yourself\n"} "bye" { send " Good bye\n"} } [root@centos8 ~]#expect expect1.1> expect { +> "hi" { send "You said hi\n"} +> "hehe" { send "Hehe yourself\n"} +> "bye" { send " Good bye\n"} +> } bye Good bye expect1.2>
#传输文件要输yes就自动输入yes ,要输入密码就自动输入密码 [root@centos7: script]#vim expect 1 #!/usr/bin/expect 2 spawn scp /etc/fstab 10.0.0.72:/data 3 expect { 4 "yes/no" { send "yes\n";exp_continue } 5 "password" { send "123456\n" } 6 } 7 expect eof [root@centos7: script]#chmod +x expect [root@centos7: script]#./expect spawn scp /etc/fstab 10.0.0.72:/data root@10.0.0.72's password: fstab ~
[root@centos7: script]#cat expect2 #!/usr/bin/expect spawn ssh 10.0.0.72 expect { "yes/no" { send "yes\n";exp_continue } "password" { send "123456\n" } } interact #表示登陆进来之后还能够交互
[root@centos7: script]#cat expect3 #!/usr/bin/expect set ip 10.0.0.72 #设置变量 set user root set password 123456 set timeout 10 #此处是超时时间 spawn ssh $user@$ip expect { "yes/no" { send "yes\n";exp_continue } "password" { send "$password\n" } } interact
[root@centos7: script]#cat expect4 #!/usr/bin/expect set ip [lindex $argv 0] #一串至关于$1 set user [lindex $argv 1] set password [lindex $argv 2] spawn ssh $user@$ip expect { "yes/no" { send "yes\n";exp_continue } "password" { send "$password\n" } } interact [root@centos7: script]#./expect4 10.0.0.72 root 123456 spawn ssh root@10.0.0.72 root@10.0.0.72's password: Last login: Tue May 18 09:58:08 2021 from 10.0.0.73
#远程登陆且建立帐号 [root@centos7: script]#vim expect5 1 #!/usr/bin/expect 2 set ip [lindex $argv 0] 3 set user [lindex $argv 1] 4 set password [lindex $argv 2] 5 set timeout 10 6 spawn ssh $user@$ip 7 expect { 8 "yes/no" { send "yes\n";exp_continue } 9 "password" { send "$password\n" } 10 } 11 expect "]#" { send "useradd haha\n" } 12 expect "]#" { send "echo magedu |passwd --stdin haha\n" } 13 send "exit\n" 14 expect eof #执行完之后还退出 ~ [root@centos7: script]#./expect5 10.0.0.72 root 123456 spawn ssh root@10.0.0.72 root@10.0.0.72's password: Last login: Tue May 18 09:58:57 2021 from 10.0.0.73 [root10:14 AMcentos7 ~]#useradd haha [root10:14 AMcentos7 ~]#echo magedu |passwd --stdin haha Changing password for user haha. passwd: all authentication tokens updated successfully. [root10:14 AMcentos7 ~]#exit logout Connection to 10.0.0.72 closed.
[root@centos7: script]#cat expect6.sh #!/bin/bash ip=$1 user=$2 password=$3 expect <<EOF set timeout 20 spawn ssh $user@$ip expect { "yes/no" { send "yes\n";exp_continue } "password" { send "$password\n" } } expect "]#" { send "useradd hehe\n" } expect "]#" { send "echo magedu |passwd --stdin hehe\n" } expect "]#" { send "exit\n" } expect eof EOF
[root@centos7: script]#cat expect.user.sh #!/bin/bash NET=10.0.0 user=root password=123456 for ID in 72 73 129;do ip=$NET.$ID expect <<EOF set timeout 4 spawn ssh $user@$ip expect { "yes/no" { send "yes\n";exp_continue } "password" { send "$password\n" } } expect "#" { send "useradd test\n" } expect "#" { send "exit\n" } expect eof EOF done
[root@centos7: script]#cat expect.firewalld.sh #!/bin/bash NET=10.0.0 user=root password=123456 for ID in 72 73 ;do ip=$NET.$ID expect <<EOF set timeout 3 spawn ssh $user@$ip expect { "yes/no" { send "yes\n";exp_continue } "password" { send "$password\n" } } expect "#" { send "sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config\n" } expect "#" { send "setenforce 0\n" } expect "#" { send "exit\n" } expect eof EOF done
declare -a 列出全部的数组
数组介绍
变量:存储单个元素的内存空间
数组:存储多个元素的连续的内存空间,至关于多个变量的集合
数组名和索引
索引的编号从0开始,属于数值索引
索引可支持使用自定义的格式,而不只是数值格式,即为关联索引,bash4.0版本以后开始支持
bash的数组支持稀疏格式(索引不连续)
数组赋值
数组元素的赋值
(1) 一次只赋值一个元素
ARRAY_NAME[INDEX]=VALUE weekdays[0]="Sunday" weekdays[4]="Thursday"
(2) 一次赋值所有元素
ARRAY_NAME=("VAL1" "VAL2" "VAL3" ...)
范例:
title=("ceo" "coo" "cto") [root@centos7: ~]#echo ${title[*]} ceo coo cto [root@centos7: ~]#echo $title ceo [root@centos7: ~]#echo ${title[@]} ceo coo cto [root@centos7: ~]#num=({1..10}) [root@centos7: ~]#echo ${num[*]} 1 2 3 4 5 6 7 8 9 10 [root@centos7: ~]#echo ${num[6]} 7 file=( *.sh )
root@centos7: ~]#read -a memu lamian paomo huimian luzhus douzi [root@centos7: ~]#echo ${memu[0]} lamian [root@centos7: ~]#echo ${memu[*]} lamian paomo huimian luzhus douzi
由于没有提早声明是数组 致使乱套
[root@centos7: ~]#mage[ceo]=mage [root@centos7: ~]#mage[cto]=wange [root@centos7: ~]#echo ${mage[ceo]} wange [root@centos7: ~]#echo ${mage[cto]} wange #数组是不能装换的 [root@centos7: ~]#declare -A mage -bash: declare: mage: cannot convert indexed to associative array #删除数组 [root@centos7: ~]#declare -A mage 申明关联数组,关联数组是随机存放的 -bash: declare: mage: cannot convert indexed to associative array [root@centos7: ~]#unset mage [root@centos7: ~]#declare -A mage [root@centos7: ~]#mage[ceo]=mage [root@centos7: ~]#mage[cto]=wang [root@centos7: ~]#echo ${mage[ceo]} mage [root@centos7: ~]#echo ${mage[cto]} wang
[root@centos7: ~]#declare -A student [root@centos7: ~]#student[1]=a [root@centos7: ~]#student[2]=b [root@centos7: ~]#student[3]=c [root@centos7: ~]#student[age1]=age1 [root@centos7: ~]#student[age2]=age2 [root@centos7: ~]#student[age3]=age3 [root@centos7: ~]#student[gender1]=m [root@centos7: ~]#student[gender2]=f [root@centos7: ~]#student[gender3]=f [root@centos7: ~]#student[city1]=city1 [root@centos7: ~]#student[city2]=city2 [root@centos7: ~]#student[city3]=city3 [root@centos7: ~]#for i in {1..50};do echo student[city$i]=${student[city$i]} ;done student[city1]=city1 student[city2]=city2 student[city3]=city3 student[city4]= student[city5]=
num[6]=6 下标为6,便是第七个元素的值为6
[root@centos7: ~]#alpha=({a..z}) [root@centos7: ~]#echo ${alpha[@]} a b c d e f g h i j k l m n o p q r s t u v w x y z [root@centos7: ~]#echo ${alpha[@]:3:4} #跳过前三个取四个 d e f g [root@centos7: ~]#echo ${alpha[@]:3} #跳过三个取全部的 d e f g h i j k l m n o p q r s t u v w x y z [root@centos7: ~]#echo ${#alpha[@]} #多少个 26 [root@centos7: ~]#unset alpha[3] #切出来一个 [root@centos7: ~]#echo ${#alpha[@]} 就少了一个元素 25 [root@centos7: ~]#num=({0..5}) [root@centos7: ~]#num[6]=6 #给数组添加一个元素 [root@centos7: ~]#echo ${#num[@]} #如今元素的个数 7 [root@centos7: ~]#num[${#num[@]}]=7 #继续给数组中添加元素,就是将数组的个数做为数组的下标 [root@centos7: ~]#echo ${num[@]} 0 1 2 3 4 5 6 7
[root@centos7: ~]#echo ${str:3} de ================================================ #返回字符串变量var的长度 ${#var} [root@centos7: ~]#str=abcde [root@centos7: ~]#echo ${#str} 5 ================================================= #返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,到最后的部分, offset的取值在0 到 ${#var}-1 之间(bash4.2后,容许为负值) ${var:offset} ================================================ #返回字符串变量var中从第offset个字符后(不包括第offset个字符)的字符开始,长度为number的部分 ${var:offset:number} [root@centos7: ~]#str=abcde [root@centos7: ~]#echo ${str:2:3} #从第二个开始,取三个 cde ==================================================== #取字符串的最右侧几个字符,取字符串的最右侧几个字符, 注意:冒号后必须有一空白字符 ${var: -length} [root@centos7: ~]#echo ${str: -2} #从后往前取2个 de ================================================== #从最左侧跳过offset字符,一直向右取到距离最右侧lengh个字符以前的内容,即:掐头去尾 ${var:offset:-length} [root@centos7: ~]#str=abcdefg [root@centos7: ~]#echo ${str: 3 : -2 } #掐头去尾 de ======================================= #先从最右侧向左取到length个字符开始,再向右取到距离最右侧offset个字符之间的内容,注意:- length前空格 ${var: -length:-offset} [root@centos7: ~]#str=abcdefg [root@centos7: ~]#echo ${str: -4: -1 } def [root@centos7: ~]#echo ${str: -4: -2 }倒数第四个和倒数第二个之间的内容 de #两个都是负数,后面的负数要大于前面的数字
[root@centos8 ~]#file="var/log/messages" [root@centos8 ~]#echo ${file#*/}从左到右 log/messages [root@centos8 ~]#echo ${file##*/} 贪婪模式 messages
[root@centos8 ~]#file="var/log/messages" [root@centos8 ~]#echo ${file%/*} #从右往左找。找到/,将其后面的内容删除 var/log [root@centos8 ~]#echo ${file%%/*} 贪婪模式 var
#把var中的全部小写字母转换为大写 ${var^^} #把var中的全部大写字母转换为小写 ${var,,}
[root@centos7: ~]#str=wang;var=${str-"haha"};echo var=$var var=wang [root@centos7: ~]#str=;var=${str-"haha"};echo var=$var var= [root@centos7: ~]#unset str;var=${str-"haha"};echo var=$var var=haha
declare [选项] 变量名 选项: -r 声明或显示只读变量 -i 将变量定义为整型数 -a 将变量定义为数组 -A 将变量定义为关联数组 -f 显示已定义的全部函数名及其内容 -F 仅显示已定义的全部函数名 -x 声明或显示环境变量和函数,至关于export -l 声明变量为小写字母 declare –l var=UPPER -u 声明变量为大写字母 declare –u var=lower
eval命令将会首先扫描命令行进行全部的置换,而后再执行该命令。该命令适用于那些一次扫描没法实
现其功能的变量,该命令对变量进行两次扫描
[root@centos7: ~]#n=10 [root@centos7: ~]#for i in {1..$n};do echo i=$i ;done i={1..10} [root@centos7: ~]#for i in `eval echo {1..$n}`;do echo i=$i ;done i=1 i=2 i=3 i=4 i=5 i=6 i=7 i=8 i=9 i=10 [root@centos8 ~]#i=1 [root@centos8 ~]#j=a [root@centos8 ~]#$j$i=hello -bash: a1=hello: command not found [root@centos8 ~]#eval $j$i=hello [root@centos8 ~]#echo $j$i a1
若是第一个变量的值是第二个变量的名字,从第一个变量引用第二个变量的值就称为间接变量引用
variable1的值是variable2,而variable2又是变量名,variable2的值为value,间接变量引用是指经过
variable1得到变量值value的行为
[root@centos8 ~]#cat test.sh #!/bin/bash ceo=mage title=ceo declare -n ref=$title [ -R ref ] && echo reference echo $ref ceo=wang echo $ref [root@centos8 ~]#bash test.sh reference mage wang
[root@centos8 ~]#ceo=name [root@centos8 ~]#name=mage [root@centos8 ~]#echo $ceo name [root@centos8 ~]#echo $$ceo $$表示当前的进程的PID 33722ceo [root@centos8 ~]#echo $BASHPID 33722 [root@centos8 ~]#echo \$$ceo $name [root@centos8 ~]#eval tmp=\$$ceo [root@centos8 ~]#echo $tmp mage [root@centos8 ~]#echo ${!ceo} mage [root@server ~]# NAME=wangxiaochun [root@server ~]# N=NAME [root@server ~]# N1=${!N} [root@server ~]# echo $N1 wangxiaochun [root@server ~]# eval N2=\$$N [root@server ~]# echo $N2 wangxiaochun