04.17 Shell高级编程
2017-07-12 09:14
671 查看
第一章 Shell环境变量
1. 什么是变量变量就是用一个固定的字符串(也可能是字符数字等的组合),替代更多更复杂的内容,这个内容里可能还会包含变量和路径,字符串等其他内容。变量的定义是存在内存中。
x=1 y=2
2. 变量类型
a)环境变量/全局变量
可以在创建他们的Shell及其派生出来的字Shell中使用。环境变量又可以分为自定义环境变量和bash内置的环境变量。
b) 局部变量/普通变量
只能在创建他们的Shell函数或Shell脚本中使用,我们创建的一般是普通变量。
3. 和变量相关的配置文件
[root@Never-downtime scripts]# ll /etc/profile /etc/bashrc ~/.bashrc ~/.bash_profile /etc/profile.d/ -rw-r- 4000 -r-- 1 root root 2730 Apr 16 14:23 /etc/bashrc -rw-r--r-- 1 root root 1860 Mar 28 22:36 /etc/profile -rw-r--r--. 1 root root 176 May 20 2009 /root/.bash_profile -rw-r--r--. 1 root root 176 Sep 23 2004 /root/.bashrc
4. 设置全局变量(环境变量)的方法
(1)变量名大写 (2)使用export定义 (3)全局生效放在/etc/bashrc (4)局部生效放在~/.bashrc
5. 变量文件开机启动顺序
6. 位置变量
$0获取当前执行的shell脚本的文件名,如果执行脚本带路径那么就包括脚本路径。
condrestart|try-restart) rh_status_q || exit 0 restart ;; *) echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}" exit 2 esac exit $?
$n 获取当前执行的shell脚本的第n个参数值,n=1..9,当n为0时表示脚本的文件名,如果n大于9用大括号括起来{10},参数以空格隔开。
$# 获取当前执行的shell脚本后面接的参数的总个数。
7. 进程状态变量
$? 获取执行上一个指令的返回值(0位成功,非0为失败)
返回值 | 含义 |
---|---|
0 | 表示运行成功 |
2 | 权限拒绝 |
1~125 | 表示运行失败,脚本命令、系统命令错误或参数传递错误 |
126 | 找到该命令,但无法执行 |
127 | 未找到要运行的命令 |
>128 | 命令被系统强制结束 |
第二章 变量的数值运算
运算 | 含义 |
---|---|
++ – | 增加及减少,可前置也可放结尾 |
+ - ! ~ | 一元的正好与符号,非,逻辑与位的取反 |
* / % | 乘法、除法、取余 |
< <= > >= | 比较符号 |
== != | 相等、不相等 |
<< >> | 向左位移,向右位移 |
& | 位的AND |
^ | 位的异 |
| | 位的或 |
&& | 位的AND |
|| | 位的OR |
?: | 条件表达式 |
= += -= *= /= %= &= ^= <<= >>= |= | 赋值运算符 |
** | 幂运算 |
[root@CentOS7 ~]# ((a=1+2**3-4%3)) [root@CentOS7 ~]# echo $a 8 [root@CentOS7 ~]# b=$((1+2**3-4%3)) [root@CentOS7 ~]# echo $b 8 [root@CentOS7 ~]# echo $((1+2**3-4%3)) 8
1. 【$(())】
同$(()) [root@Never-downtime tmp]# echo $[2+3] 5 [root@Never-downtime tmp]# echo $[2*3] 6
2. 数值判断
[root@CentOS7 ~]# echo $((4>2)) 1 [root@CentOS7 ~]# echo $((4<2)) 0
第三章 read读入
1. 功能说明Read lines from a file into an array variable
read命令从标准输入中读取一行,并把输入行的每个字段的值指定给shell变量。
2. 选项参数
-p prompt 设置提示信息
-t timeout 设置输入超时时间,单位s。
[root@CentOS7 ~]# read -p "qing shu ru yige zhi:" a qing shu ru yige zhi:3 [root@CentOS7 ~]# echo $a 3
3. 清楚赋值变量unset
[root@CentOS7 ~]# unset a [root@CentOS7 ~]# echo $a
4. 实现一个加减乘除的计算器
[root@Never-downtime scripts]# vi read2.sh #!/bin/bash read -p "请输入2个值:" a b echo "$a+$b=$(($a+$b))" echo "$a-$b=$(($a-$b))" echo "$a*$b=$(($a*$b))" echo "$a/$b=$(($a/$b))" [root@Never-downtime scripts]# sh read2.sh 请输入2个值:6 2 6+2=8 6-2=4 6*2=12 6/2=3 [root@Never-downtime scripts]# sh read2.sh 请输入2个值:2 8 2+8=10 2-8=-6 2*8=16 2/8=0
第四章 测试表达式
1. 常用文件测试操作符号常用文件测试操作符号 | 说明 |
---|---|
-f 文件,英文file | 文件存在且为普通文件则真,即测试表达式成立。 |
-d文件,英文directory | 文件存在且为目录文件则真,即测试表达式成立。 |
-s文件,英文size | 文件存在且为文件大小不为0则真,即测试表达式成立。 |
-e文件,英文exist | 文件存在则真,即测试表达式成立,只要有文件就行,区别-f |
-r文件,英文read | 文件存在且可读则真,即测试表达式成立。 |
-w文件,英文write | 文件存在且可写则真,即测试表达式成立。 |
-x文件,英文executable | 文件存在且可执行则真,即测试表达式成立。 |
-L文件,英文link | 文件存在且为链接文件则真,即测试表达式成立。 |
f1 -nt f2,英文newer than | 文件f1比文件f2新则真,即测试表达式成立,根据文件修改时间计算。 |
f1 -ot f2,英文older than | 文件f1比文件f2旧则真,即测试表达式成立,根据文件修改时间计算。 |
字符串测试操作符的作用:比较两个字符串是否相同、字符串长度是否为零,字符串是否为NULL。Bash区分零长度字符串和空字符串。
常用字符串测试操作符 | 说明 |
---|---|
-z “字符串” | 若串长度为0则真,-z理解为zero |
-n “字符串” | 若串长度不为0则真,-n理解为no zero |
“串1” = “串2” | 若串1等于串2则真,可以使用”==”代替”=” |
“串1” != “串2” | 若串1不等于串2则真,但不能使用”!==”代替”!=” |
[ “$password” = “john” ]中[ “$password” = “john” ]之间必须存在空格。
引号可以不加,遇到空格必须加,但是推荐使用引号!
3. 整错错误示例
正确 | 中括号、引号、空格 | [ “abc” = “abc” ] && echo “eq” |
错误 | 中括号、引号 | [ “abc”=”ac” ] && echo “eq” |
错误 | 中括号 | [ abc=bc ] && echo “eq” |
在[]中使用的比较符 | 说明 |
---|---|
-eq | equal等于 |
-ne | not equal大等于 |
-gt | greater than 大于 |
-ge | greater equal 大于等于 |
-lt | less than 小于 |
-le | less equal 小于等于 |
在[]中使用的逻辑操作符 | 说明 |
---|---|
-a | 与and,两端都为真则真 |
-o | 或or,有一个真就真 |
! | 非not,相反则为真 |
综合实战案例:开发shell脚本分别实现以脚本传参以及read读入的方式比较2个整数大小。用条件表达式(禁止if)进行判断并以屏幕输出的方式提醒用户比较结果。注意:一共是开发2个脚本。当用脚本传参以及read读入的方式需要对变量是否为数字、并且传参个数不对给予提示。
#!/bin/bash a=$1 b=$2 [ "$#" -ne 2 ] && echo "警告:这里必须输入两个字符" && exit 1 zimu1=`echo $1|sed 's#[0-9]##g'` zimu2=`echo $2|sed 's#[0-9]##g'` [ -n "${zimu1}" ] && echo "警告:第一个字符类型必须是数字" && exit 2 [ -n "${zimu2}" ] && echo "警告:第二个字符类型必须是数字" && exit 2 [ $a -eq $b ] && echo "$a = $b" [ $a -gt $b ] && echo "$a > $b" [ $a -lt $b ] && echo "$a < $b"
read读入 read -t 5 -p "提示:请输入2个字符" a b [ -z "$a" -o -z "$b" ] && echo "必须是两个字数" && exit 1 replace1=$(echo $a |sed "s#[0-9]##g") replace2=$(echo $b |sed "s#[0-9]##g") [ -n "$replace1" ] && echo "警告:第一个字符类型必须是数字" && exit 2 [ -n "$replace2" ] && echo "警告:第二个字符类型必须是数字" && exit 2 [ "$a" -eq "$b" ] && echo "$a = $b" && exit [ "$a" -gt "$b" ] && echo "$a > $b" && exit [ "$a" -lt "$b" ] && echo "$a < $b" && exit
第五章 if条件语句
1. if单分支条件句语if [条件] then 指令 if 或 if [条件];then 指令 fi 提示:分号相当于命令换行,上面两种语法等同。 特殊写法if [ -f "$file" ];then echo 1 ;fi 相当于[ -f "$file" ] && echo 1
[root@Never-downtime scripts]# vi size_Comparison1.sh #!/bin/bash a=$1 b=$2 if [ "$#" -ne "2" ] then echo "警告:这里必须输入两个字符" && exit 1 fi replace1=$(echo $1 |sed "s#[0-9]##g") replace2=$(echo $2 |sed "s#[0-9]##g") if [ -n "$replace1" ] then echo "警告:第一个字符类型必须是数字" && exit 2 fi if [ -n "$replace2" ] then echo "警告:第二个字符类型必须是数字" && exit 2 fi if [ "$a" -eq "$b" ] then echo "$a = $b" fi if [ "$a" -gt "$b" ] then echo "$a > $b" fi if [ "$a" -lt "$b" ] then echo "$a < $b" fi
2. if双分支条件语句
if [ 条件 ] then 指令1 else 指令2 fi
3. 判断是否为文件
[root@Never-downtime scripts]# vi iftuo.sh #!/bin/bash if [ -f "read1.sh" ] then echo 0 else echo 1 fi 相当于[ -f "read1.sh" ] && echo 0 || echo 1
4. if多分支语句
if [ 条件1 ] then 指令1 elif [ 条件2 ] then 指令2 elif [ 条件3 ] then 指令3 elif [ 条件4 ] then 指令4 .... else 指令n fi
5. 判断两个数字的大小
23 if [ "$a" -eq "$b" ] 24 then 25 echo "$a=$b" 26 27 elif [ "$a" -gt "$b" ] 28 then 29 echo "$a>$b" 30 31 else [ "$a" -lt "$b" ] 32 echo "$a<$b" 33 fi
6. if语句总结
分支 | 语法 | 结果 |
---|---|---|
单分支 | if then fi | 一个条件一个结果 |
双分支 | if then else fi | 一个条件两个结果 |
多分支 | if then elif elif else fi | 多个条件多个结果 |
第六章 for循环结构语法
for 变量名 in 变量取值列表 do 指令..... done
1. 示例循环10次
[root@Never-downtime scripts]# for i in {00..10} > do > echo $i > done 00 01 02 03 04 05 06 07 08 09 10 [root@Never-downtime scripts]# for i in {00..10}; do echo $i; done
2. 小结
in后面的字符个数控制循环的次数 将i后面的字符分别赋值给变量i,在do后面可以引用变量i也可以不用 以空格区分,[root@oldboyedu-35 data]# for i in {1..10};do useradd test$i;done
第七章 获取随机数的几种方法
1. 通过系统变量$RANDON[root@CentOS7 ~]# echo $RANDOM 9820 [root@CentOS7 ~]# echo $RANDOM 1468 [root@CentOS7 ~]# echo $RANDOM 14955
2. 通过openssl产生
[root@CentOS7 ~]# openssl rand -base64 8|md5sum b025e02d40e910f8a9cd36f98ff363d7 - [root@CentOS7 ~]# openssl rand -base64 8|md5sum 6a9619eab8009f0ca5f56a82475c2077 -
3. echo $(date +%N)
[root@CentOS7 ~]# echo $(date +%N) 216956783 [root@CentOS7 ~]# echo $(date +%N) 349010758 [root@CentOS7 ~]# echo $(date +%N) 773229182
4. urandom
[root@CentOS7 ~]# head /dev/urandom |cksum 3017719303 1809 [root@CentOS7 ~]# head /dev/urandom |cksum 1901402952 1933 [root@CentOS7 ~]# head /dev/urandom |cksum 3354308804 2453
5. uuidgen码有硬件、时间、机器当前运行信息等组成,理论上在互联网中唯一
[root@CentOS7 ~]# uuidgen 93841c31-0664-462d-8a28-a406b3791bb0 [root@CentOS7 ~]# uuidgen bfb2487f-5cbd-4daa-b847-9870920a706c [root@CentOS7 ~]# uuidgen cce1d3c9-041a-4cd8-a3a0-1b399fee4c51
第八章 case结构条件句语法
case “字符串标量” in 值1) 指令1 ;; 值2) 指令1 ;; *) 指令 esac #注:case语句相当于一个if的多分支结构语句
1. case语句小结
case语句就相当于多分支的if语句。case语句的优势是更规范、易读。
case语句适合变量的值少,且为固定的数字或字符串集合。(1,2,3)或(start,stop,restart)。
系统服务启动脚本传参的判断多用case语句,多参考rpcbind/nfs/crond脚本。
结合示例:打印选择菜单,按照选择一键安装不同的web服务。 shmenu.sh 1.[install lamp] 2.[install lnmp] 3.[exit] pls input the num you want: 要求: 1、当用户输入1时,输出“startinstalling lamp提示”。然后执行/servsr/scripts/lamp.sh。脚本内容输出“lampis installed”后退出脚本, lamp一键安装脚本。 2、当用户输入2时,输出“startinstalling lnmp提示”,然后执行/server/scripts/lnmp.sh。脚本内容输出“lnmpis installed”后退出脚本, lnmp一键安装脚本。 3、当输入3时,退出当前菜单及脚本。 4、当输入任何其它字符,给出提示“Input error”后退出脚本。 5、要对执行的脚本进行相关的条件判断,例如:脚本文件是否存在,是否可执行等判断,尽量用上前面讲解的知识点。
[root@Never-downtime scripts]# vi case.sh #!/bin/bash cat<<EOP 本程序支持安装的服务: 1.安装LAMP服务 2.安装LNMP服务 3.exit 退出安装 EOP read -p "请输入你的选择:" a case $a in 1) echo "startinstalling lamp" lampScripts=/server/scripts/lamp.sh [ -f $lampScripts ] && sh $lampScripts || exit 2 ;; 2) echo "startinstalling lnmp" lnmpScripts=/server/scripts/lnmp.sh [ -f $lnmpScripts ] && sh $lnmpScripts || exit 3 ;; 3) exit ;; *) echo "您的输入有误,请重新输入" ;; esac
第九章 Linux色值 彩色字体值
echo -e "\033[30m 黑色字oldboy trainning \033[0m" echo -e "\033[31m 红色字oldboy trainning \033[0m" echo -e "\033[32m 绿色字oldboy trainning \033[0m" echo -e "\033[33m 黄色字oldboy trainning \033[0m" echo -e "\033[34m 蓝色字oldboy trainning \033[0m" echo -e "\033[35m 紫色字oldboy trainning \033[0m" echo -e "\033[36m 天蓝字oldboy trainning \033[0m" echo -e "\033[37m 白色字oldboy trainning \033[0m"
第十章 Linux色值 彩底白字值
echo -e "\033[40;37m 黑底白字 welcome to old1boy\033[0m" echo -e "\033[41;37m 红底白字 welcome to old2boy\033[0m" echo -e "\033[42;37m 绿底白字 welcome to old3boy\033[0m" echo -e "\033[43;37m 黄底白字 welcome to old4boy\033[0m" echo -e "\033[44;37m 蓝底白字 welcome to old5boy\033[0m" echo -e "\033[45;37m 紫底白字 welcome to old6boy\033[0m" echo -e "\033[46;37m 天蓝白字 welcome to old7boy\033[0m" echo -e "\033[47;30m 白底黑字 welcome to old8boy\033[0m"
第十一章 while条件句
while 条件 do 指令 done
[root@Never-downtime ~]# vi while.sh #!/bin/bash while true do uptime >>/tmp/uptime.log sleep 1 done [root@Never-downtime ~]# tailf /tmp/uptime.log 09:29:04 up 2:00, 4 users, load average: 0.00, 0.01, 0.04 09:29:06 up 2:00, 4 users, load average: 0.00, 0.01, 0.04 09:29:08 up 2:00, 4 users, load average: 0.00, 0.01, 0.04 09:29:10 up 2:00, 4 users, load average: 0.00, 0.01, 0.04
第十二章 各种语句小结
1. while循环while循环的特长是执行守护进程以及我们希望循环不退出持续执行,用于频率小于1分钟循环处理(crond),其他的while循环几乎都可以被for循环替代。
2. case语句
case语句可以被if语句替换,一般在系统启动脚本传入少量固定规则字符串用case语句,其他普通判断多用if。
3. until循环
until执行死循环,表达式成立后结束循环。
until [ $# -eq 0 ] do echo $* shift done 1 2 3 4 5 2 3 4 5 3 4 5 4 5 5
第十三章 循环控制语句
continue 跳过当次循环 break 跳过整个循环 exit 退出脚本 return 退出函数
1. break
break脚本: [root@Never-downtime scripts]# vi break.sh #!/bin/bash for a in {01..10} do if [ $a -eq 5 ] then break else echo $a fi done echo "我猜你现在在看这几行字..."
输出结果: [root@Never-downtime scripts]# sh break.sh 01 02 03 04 我猜你现在在看这几行字...
2. exit
exit脚本: #!/bin/bash for a in {01..10} do if [ $a -eq 5 ] then exit else echo $a fi done echo "我猜你现在在看这几行字..."
输出结果: [root@Never-downtime scripts]# sh break.sh 01 02 03 04
3. continue
continue脚本: #!/bin/bash for a in {01..10} do if [ $a -eq 5 ] then continue else echo $a fi done echo "我猜你现在在看这几行字..."
输出内容: [root@Never-downtime scripts]# sh break.sh 01 02 03 04 06 07 08 09 10 我猜你现在在看这几行字...
相关文章推荐
- shell 编程高级技巧
- 高级shell脚本编程之重定向、环境变量、shell函数、echo命令用法
- 18道Shell高级编程企业实战题及参考答案
- linux----->shell高级编程----sed应用
- UNIX环境高级编程学习之第四章文件和目录-用C实现Shell中的"ls -l"功能
- shell 高级编程(1)
- Linux学习-高级shell脚本编程(一)函数的妙用
- shell脚本高级编程
- Shell脚本高级编程 一 初识sed和gawk
- Shell 编程9(高级变量)
- Linux&shell之高级Shell脚本编程-创建菜单
- Linux&shell之高级Shell脚本编程-创建函数
- Linux学习-高级shell脚本编程(二)初识sed和gawk
- *Linux Shell 高级编程技巧2----shell工具
- C++高级开发之一 Shell扩展编程
- 查看进程第二部分 Linux Shell高级编程技巧——第二章 Shell工具
- linux----->shell高级编程----1
- Shell脚本高级编程 二 正则表达式