什么是是shell?html
shell原意,是贝壳,linux
它在Linux内核和应用程序之间。就像一个翻译官,中间人,让程序员员写的应用程序能和系统之间相互交流nginx
什么是shell脚本?程序员
简单点说,就是许多shell命令,写在一个文件中,实现一个需求web
先看一个清除日志的脚本面试
# clean logs ,v0.1 cd /var/log cat /dev/null>message echo "Logs clean up"
这个脚本的问题在于,三条命令之间没有表现明确的关系正则表达式
咱们不知道脚本执行后,会是什么样的结果!shell
下面看一个完善的版本编程
#! /bin/bash LOG_DIR=/var/log ROOT_UID=0 # 第一关,必须是root用户才能执行脚本,不然提示,并终止 if ['$UID' -ne '$ROOT_UID'] then echo 'Must be root to run this script!' exit 1 fi # 第二关,成功切换到目录,不然提示,并终止 cd $LOG_DIR || { echo 'Can not change to necessary directory!' exit 1 } # 第三关,清理日志,若是清理成功,给出正确的提示 cat /dev/null>message && { echo 'Logs cleaned up!' exit 0 } # 第四关,通关失败,给出提示 echo 'cleaned logs fail!' exit 1
Shell脚本语言很擅长处理纯文本类型的数据,而Linux系统中几乎全部的配置文件、日志文件(如NFS、 Rsync、 Httpd、 Nginx、 LVS、 MySQL等),以及绝大多数的启动文件都是纯文本类型的文件。vim
天然学好Shell脚本语言,就能够利用它在Linux系统中发挥巨大的做用。
形象的将shell和各类运维工具比喻为一串项链以及三种SHELL语言分类
一个规范的Shell脚本在第一行会指出由哪一个程序(解释器)来执行脚本中的内容,这一行内容在Linux bash编程中通常为:
#!/bin/bash或#!/bin/sh #<==255个字符之内
早期的bash与sh稍有不一样,它还包含了csh和ksh的特点,但大多数脚本均可以不加修改地在sh上运行。
CentOS和Red Hat Linux下默认的Shell均为bash。所以,在写Shell脚本的时候,脚本的开头即便不加#!/bin/bash,它也会交给bash解释。
若是写脚本不但愿使用系统默认的Shell解释,那么就必需要指定解释器了。不然脚本文件执行的结果可能就不是你想要的。
建议读者养成好的编程习惯,无论什么脚本最好都加上相应的开头解释器语言标识,养成Shell编程规范。
这是当脚本文件自己没有可执行权限(即文件权限属性x位为-号)时常使用的方法,或者脚本文件开头没有指定解释器时须要使用的方法,这也是老男孩老师推荐的使用方法
指在当前路径下执行脚本(脚本要有执行权限),须要先将脚本文件的权限改成可执行(即文件权限属性加x位),
具体方法为chmod +x script-name。而后经过脚本绝对路径或相对路径就能够直接执行脚本了。
关于点和souece的妙用,就是父子shell之间能够相互调用变量
[root@dao scripts]# sh sh_user.sh # 文件中是user=‘whoami’ 至关于定义了局部变量 [root@dao scripts]# echo $user [root@dao scripts]# . ./sh_user.sh # 使用点,调用了子变量(局部变量) [root@dao scripts]# echo $user whoami
[root@dao scripts]# chkconfig --list |grep 3:on |awk '{print "chkconfig",$1,"off"}'|bash
当咱们登录命令行,就至关于开启一个shell,也就是局部变量和全局变量的意思,只能在建立他们的shell函数或者shell脚本中使用。
http://www.javashuo.com/article/p-pnajmbxv-m.html
取消定义变量unset user
shell中批量注释
一、vim批量操做
二、:EOF
EOF (这个EOF前面不能有空格)原理就是,EOF把中间的内容交给冒号,可是冒号表示什么都不作,因此,也就是注释了
三、cat > /dev/null <<EOF
EOF
shell脚本的执行过程
shell脚本的编程规范和习惯
1.开头加脚本解释器 2.附带做者及版权信息 3.脚本扩展名为*.sh 4.脚本存放在固定的目录下 5.脚本中不用中文 6.成对的符号一次书写完成 7.循环格式一次性输入完成
什么是变量?
x=1,x就是变量名,=号表示赋值。用一个字符或者字符串表示一堆内容。这个字符或者字符串叫作变量
变量的特性?
在bash shell中不会区分变量的类型
变量的分类?
两类,环境变量(全局变量)和普通变量(局部变量)。http://www.javashuo.com/article/p-pnajmbxv-m.html
环境变量(全局变量),系统中默认就存在的,做用就是解决系统的一些问题。
显示环境变量的方法:
一、echo $变量名
二、env
三、set set -o 查看bash编程的配置
定义环境变量:
PS一、PATH、HOME、UID 系统固有的,默认就表示必定意义。
3种定义环境变量的方法(环境变量尽可能大写)
一、直接export
export PIZZA=1
二、先赋值,在export
PIZZA=2
export PIZZA
三、declare
-x A=1
-i 表示定义整型
环境变量永久生效的配置/etc/profile
环境变量取消 unset PIZZA
全局文件
/etc/profile
/etc/bashrc/
用户环境变量文件
~/.bashrc
~/.bash_profile
上图是文件加载的顺序
注意:新添加的环境变量要加在文件的前面,不要加在最后面,其中的代码会影响执行顺序。
注意:在ssh 远程登陆或者其余特殊状况下,也许不会加载/etc/profile和~/.bash_profile
因此在添加变量的时候,添加在/etc/bashrc下
局部变量
当前用户或者脚本中生效
a.变量名: 规则:字母、数字、下划线,3者组合,以字母开头。 要求:见名知意。 1)OldboyAge=1 2)oldboy_age=1 3) oldboyAge=1 ###驼峰语法 b.变量内容 字符串: 变量名=value #<==不加引号。 ##解析变量或者命令,而后输出,纯数字选择不加引号。 变量名=’value’ #<==加单引号。 ###所见即所得 变量名=”value” #<==加双引号。 ##解析变量或者命令,而后输出,字符串默认选择双引号,能够把要定义的内容做为一个总体。 命令变量,把一个命令的结果赋值给变量 变量名=`ls` 变量名=$(ls)
小结:
针对变量名:
一、变量名必定要有必定的命令规范,而且要见名知意,推荐使用驼峰法
二、变量名仅能使用字母、数字、下划线的任意多个字符,而且要字母开头
针对变量内容:
三、在脚本中定义普通字符变量,尽可能使用双引号括起来。
四、单纯数字的变量内容能够不加引号
五、但愿变量的内容鸳鸯输出需加单引号
六、但愿变量值引用命令并获取命令的结果就用反引号或者$()
针对赋值符号:
七、变量定义使用赋值等号(=),赋值符号两端不要有空格
针对变量输出:
八、使用或者输出变量的内容,可用 $ 变量名,$PS1
九、若变量名(db)后面有其余字符连接的时候,就必需给变量名加上大括号
在Shell中存在一些特殊且重要的变量,例如: $0、 $1、 $#,咱们称之为特殊位置参数变量,
要从命令行、函数、或脚本执行等处传递参数时,就须要在Shell脚本中使用位置参数变量。
特殊位置变量: $0 获取脚本的名字,若是脚本前面跟着路径的话,那就获取路径加上脚本名字。 [root@web01 scripts]# cat test.sh #!/bin/bash echo $0 [root@web01 scripts]# bash test.sh test.sh [root@web01 scripts]# bash /server/scripts/test.sh /server/scripts/test.sh 企业应用; 通常在启动脚本的结尾会使用$0获取脚本的路径和名字给用户提示用。 /etc/init.d/crond $1,$2----$n $1表示脚本后的第一个参数 $2表示脚本后的第二个参数 .... 超过$9,${10} 要加{}大括号 企业应用: case "$1" in start) rh_status_q && exit 0 $1 ;; stop) $# 脚本后面全部参数的个数 企业应用: [root@web01 scripts]# cat test.sh #!/bin/bash if [ $# -ne 2 ] then echo "Usage:$0 arg1 arg2" exit 1 fi echo ok $* 获取脚本的全部参数,“$1 $2 $3” $@ 获取脚本的全部参数,"$1" "$2" "$3" 当须要接收脚本后面全部参数时,可是又不知道参数个数就用这两个变量。 区别: [root@web01 scripts]# cat test.sh #!/bin/bash for arg in "$*" do echo $arg done echo -------------------------- for arg1 in "$@" do echo $arg1 done [root@web01 scripts]# bash test.sh "I am" oldboy teacher. I am oldboy teacher. -------------------------- I am oldboy teacher. make echo $?
$? 获取上一个命令的返回值,若是返回值为0就证实上一个命令执行正确, 非0,就证实上一个命令执行失败的。 ***** $$ 获取当前执行脚本的进程号 $! 获取上一个后台工做进程的进程号 $_ 获取上一个执行脚本的最后一个参数
Shell变量子串(变量内容相关知识) [root@web01 scripts]# oldboy="I am oldboy" [root@web01 scripts]# echo ${oldboy} I am oldboy [root@web01 scripts]# echo ${#oldboy} 11 [root@web01 scripts]# echo $oldboy|wc -L 11 [root@web01 scripts]# expr length "$oldboy" 11 [root@web01 scripts]# echo $oldboy|awk '{print length}' 11 [root@web01 scripts]# echo $oldboy|awk '{print length ($1)}' 1 [root@web01 scripts]# echo $oldboy|awk '{print length ($0)}' 11 练习题: I am oldboy I teach linux 打印这些字符串中字符数小于3的单词。 涉及知识点:取字符串长度,for,if。 [root@web01 scripts]# echo ${oldboy:2} am oldboy [root@web01 scripts]# echo ${oldboy:2:2} am [root@web01 scripts]# echo ${oldboy:2:4} am o OLDBOY=abcABC123ABCabc [root@web01 scripts]# echo ${OLDBOY} abcABC123ABCabc [root@web01 scripts]# echo ${OLDBOY%a*C} abcABC123ABCabc [root@web01 scripts]# echo ${OLDBOY%a*c} abcABC123ABC [root@web01 scripts]# echo ${OLDBOY%%a*c} [root@web01 scripts]#
只挑了4个,最重要的是第1个
[root@web-01 ~]# [root@web-01 ~]# result=${test:-UNSET} [root@web-01 ~]# echo $test [root@web-01 ~]# echo $result UNSET [root@web-01 ~]# echo $test [root@web-01 ~]# #当变量test为空的时候,就把UNSET内容赋值给result
result 媳妇
test 销售 空
UNSET 备胎 赋值给result
企业用途
find $path -name "*.name" -mtime +7|xrangs rm -f
当 $path 为空的时候,命令会从根目录开始删,因此咱们准备一个备胎
find ${path:-/tmp} -name "*.name" -mtime +7|xrangs rm -f
系统中的应用---httpd的启动脚本中
- = ? +
若是要执行算术运算,就离不开各类运算符号,和其余编程语言相似, Shell也有不少算术运算符,下面就给你们介绍下常见的Shell算术运算符
只适合整数运算 1、(()) 推荐 2、let 次推荐 3、expr 4、$[] 既适合整数,又适合小数运算。 1、bc 2、awk 推荐
(())
[root@web-01 ~]# a=1
[root@web-01 ~]# b=2
[root@web-01 ~]# echo $a+1 不加
1+1
[root@web-01 ~]# $(a+1) 更不加了
-bash: a+1: command not found
[root@web-01 ~]# echo $(a+1)
-bash: a+1: command not found
[root@web-01 ~]# echo $((a+1)) 双括号才加
2
[root@web01 scripts]# echo $((2**3))
8
[root@web01 scripts]# echo $((1+2**3-5/3))
8
[root@web01 scripts]# echo $((1+2**3-5%3))
7
问? ++a 和 a++有什么区别
let
[root@web-01 ~]# a=1
[root@web-01 ~]# b=2
[root@web-01 ~]# i=$a+$b
[root@web-01 ~]# echo $i
1+2
[root@web-01 ~]# let i=$a+$b
[root@web-01 ~]# echo $i
3
expr用于运算,必需要有空格
[root@web-01 ~]# expr 1 + 1
2
[root@web-01 ~]# expr 1+1
1+1
$[]
[root@web-01 ~]# echo $[2+2]
4
[root@web-01 ~]# echo $[2 + 2]
4
===========
bc 就像启动计算器,高端点用法本身在了解一下
[root@web-01 ~]# bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'.
1+1
2
3+4
7
1
1
1*1.2
1.2
[root@web-01 /server/scripts]# echo "scale=2;355/113"|bc
3.14 使用scale来保留2位小数
[root@web-01 /server/scripts]# echo "scale=3;355/113"|bc
3.141
awk的运算效果很好!运算精确,好用
[root@web-01 ~]# echo 1.1 0.5 |awk '{print $1-$2}'
0.6
在shell编程里,因为函数库不多,所以在判断字符串是否为整数时,就不是很容易的事情
能够利用expr作计算时必须是整数的规则,把一个变量或者字符串和一个一直西横竖(非0)相加,
看命了返回值是否为0。就认为作加法的变量为整数,不然就不是整数。
[root@web-01 ~]# i=pizza 将字符串赋值给i [root@web-01 ~]# expr $i + 6 &>/dev/null 把i和6相加,&>/dev/null表示不保留任何输出 [root@web-01 ~]# echo $? 输出返回值 2 非0 就证实输出了错误,证实1不是整数
[root@web-01 ~]# i=4 [root@web-01 ~]# expr $i + 6 &>/dev/null [root@web-01 ~]# echo $? 0 返回为0,则证实i的值是整数
编写一个脚原本判断变量是否是整数
[root@web-01 /server/scripts]# vim judge1.sh #!/bin/bash echo 6 + $1 &>/dev/null if [ $? -eq 0 ] then echo "$1 是整数" else echo "$1 不是整数" fi "judge1.sh" [New] 9L, 112C written [root@web-01 /server/scripts]# bash judge1.sh 123 123 是整数 [root@web-01 /server/scripts]# bash judge1.sh ll ll 是整数
二、判断文件扩展名是否符合要求
[root@web-01 /server/scripts]# vim judge2.sh 1 #!/bin/bash 2 # :冒号两边要有空格 3 expr "$1" : ".*\.txt" &>/dev/null 4 if [ $? -eq 0 ] 5 6 then 7 echo "$1 是文本" 8 else 9 echo "$1 不是文本" 10 fi ~ ~ ~ "judge2.sh" 10L, 152C written [root@web-01 /server/scripts]# bash judge2.sh old old 不是文本 [root@web-01 /server/scripts]# bash judge2.sh old.txt old.txt 是文本
expr 好有不少功能,请自行了解(man expr)
Shell变量除了能够 直接赋值 或者 脚本传参 外!还可使用read命令从标准输入中得到,
read为bash内置命令,能够经过help read查看帮助。
语法格式:read [参数] [参数]
经常使用参数以下。
-p prompt:设置提示信息
-t timeout:设置输入等待时间,单位默认为秒。
[root@web-01 /server/scripts]# read -p "请输入一个数字:" a 请输入一个数字:11 [root@web-01 /server/scripts]# echo $a 11
read通常的做用就是和用户交互
[root@web-01 /server/scripts]# read -p "请输入两个数字:" a b 请输入两个数字:12 56 [root@web-01 /server/scripts]# echo $((a+b)) 68
打印一个菜单,让用户选择要作的事情
#!/bin/bash cat <<EOF 1、install lamp 2、install lnmp 3、exit EOF read -p "请选择一个序号(必须是一个数字):" num
# 先判断一下是否是数字 expr 2 + $num &>/dev/null if [ $? -ne 0 ] then echo "usage:$0 {1|2|3}" exit 1 fi if [ $num -eq 1 ] then echo "install lamp..." elif [ $num -eq 2 ] then echo "install lamp..." elif [ $num -eq 3 ] then echo "bye" else echo "usage:$0 {1|2|3}" exit 1 fi
数值运算命令: 只适合整数运算 1、(()) 推荐 2、let 次推荐 3、expr 4、$[] 既适合整数,又适合小数运算。 1、bc 2、awk 推荐 1、(()) 推荐 [root@web01 scripts]# i=$((a+1)) [root@web01 scripts]# echo $i 2 [root@web01 scripts]# [root@web01 scripts]# echo $((a+3)) 4 [root@web01 scripts]# echo $((1+3)) 4 [root@web01 scripts]# echo $((2**3)) 8 [root@web01 scripts]# echo $((1+2**3-5/3)) 8 [root@web01 scripts]# echo $((1+2**3-5%3)) 7 2、let 次推荐 [root@web01 scripts]# let i=$a+1 [root@web01 scripts]# echo $i 2 3、expr用于运算 4、$[] ============= bc awk [root@web01 scripts]# echo 1+2|bc 3 [root@web01 scripts]# [root@web01 scripts]# echo 1.1+2|bc 3.1 [root@web01 scripts]# echo 1.1+2.3|bc 3.4 [root@web01 scripts]# echo 2.1 1.4|awk '{print $1-$2}' 0.7 [root@web01 scripts]# echo 2.1 1.4|awk '{print $1*$2}' 2.94 [root@web01 scripts]# expr 2 + 2 4 [root@web01 scripts]# expr 2 + a expr: non-numeric argument [root@web01 scripts]# echo $? 2 [root@web01 scripts]# [root@web01 scripts]# [root@web01 scripts]# [root@web01 scripts]# a=2 [root@web01 scripts]# expr 2 + $a &>/dev/null [root@web01 scripts]# echo $? 0 [root@web01 scripts]# a=oldboy [root@web01 scripts]# expr 2 + $a &>/dev/null [root@web01 scripts]# echo $? 2 [root@web01 scripts]# cat judge1.sh #!/bin/bash expr 2 + $1 &>/dev/null if [ $? -eq 0 ] then echo "$1 is 整数" else echo "$1 不是整数" fi [root@web01 scripts]# bash judge1.sh 123 123 is 整数 [root@web01 scripts]# bash judge1.sh oldboy oldboy 不是整数 root@web01 scripts]# cat judge_kuozhan.sh #!/bin/bash expr "$1" : ".*\.txt" &>/dev/null if [ $? -eq 0 ] then echo "$1 是文本" else echo "$1 不是文本" fi [root@web01 scripts]# sh judge_kuozhan.sh oldboy.txt oldboy.txt 是文本 [root@web01 scripts]# sh judge_kuozhan.sh alex.log alex.log 不是文本 [root@web01 scripts]# sh judge_kuozhan.sh peiqi.log peiqi.log 不是文本 [root@web01 scripts]# sh judge_kuozhan.sh 老男孩老师.txt 老男孩老师.txt 是文本 [root@oldboy scripts]# cat test.sh #!/bin/bash a=6 b=2 echo "a-b=$(($a-$b))" echo "a+b=$(($a+$b))" echo "a*b=$(($a*$b))" echo "a/b=$(($a/$b))" echo "a**b=$(($a**$b))" echo "a%b=$(($a%$b))" 变量的赋值: 1、定义法 a=1 2、传参法 [root@web01 scripts]# cat test7.sh #!/bin/bash a=$1 b=$2 echo "a-b=$(($a-$b))" echo "a+b=$(($a+$b))" echo "a*b=$(($a*$b))" echo "a/b=$(($a/$b))" echo "a**b=$(($a**$b))" echo "a%b=$(($a%$b))" 3、read读入,读取用户输入。 -p 提示 -t 等待用户输入的时间 read -t 30 -p "请输入一个数字:" [root@web01 scripts]# read -t 30 -p "请输入一个数字:" a 请输入一个数字:11 [root@web01 scripts]# echo $a 11 [root@web01 scripts]# a=11 [root@web01 scripts]# echo $a 11 read读入有什么做用 和用户交互。 [root@web01 scripts]# cat test6.sh #!/bin/bash read -p "请输入两个数字:" a b echo "a-b=$(($a-$b))" echo "a+b=$(($a+$b))" echo "a*b=$(($a*$b))" echo "a/b=$(($a/$b))" echo "a**b=$(($a**$b))" echo "a%b=$(($a%$b))" read企业应用 [root@web01 scripts]# cat select1.sh #!/bin/bash cat <<EOF 1.install lamp 2.install lnmp 3.exit EOF read -p "请选择一个序号(必须是数字):" num #1.判断是否为整数 expr 2 + $num &>/dev/null if [ $? -ne 0 ] then echo "Usage:$0 {1|2|3}" exit 1 fi #2.判断执行处理 if [ $num -eq 1 ] then echo "install lamp..." elif [ $num -eq 2 ] then echo "install lnmp..." elif [ $num -eq 3 ] then echo "bye." exit else echo "Usage:$0 {1|2|3}" exit 1 fi
一般,在bash的各类条件结构和流程控制结构中都要进行各类测试,而后根据测试结果执行不一样的操做,有时也会与if等条件语句相结合,来完成测试判断,减小程序运行的错误。执行测试条件表达式后一般会返回“真”或“假”,就像执行命令后的返回值为0表示真,非0表示假同样。
[ 测试表达式 ] && 命令1 | | 命令2
若是前面的表达式成功,name就执行命令1,不然执行命令2
========至关于========
if [ 测试表达式 ]
then
命令1
else
命令2
fi
当命令不少的时候
[ 测试表达式 ] && {
命令1
命令2
}| |{
命令3
命令4
}
若是前面的表达式成功,那么久执行后面命令
[ 测试表达式 ] && 命令1
若是前面表达式失败,那么就执行后面的命令
[ 测试表达式 ] | | 命令2
条件表达式 [root@web-01 /server/scripts]# [ -e /etc/hosts ] && echo 1 || echo 0 1 [root@web-01 /server/scripts]# [ -e /etc/host ] && echo 1 || echo 0 0 命令表达式 [root@web-01 /server/scripts]# (expr 1 + 1 &>/dev/null) && echo 1 || echo 0 1 [root@web-01 /server/scripts]# (expr 1 + a &>/dev/null) && echo 1 || echo 0 0
在man test 中能够找到这些内容
注意:
一、字符串就用双引号
二、等号能够用一个或者两个
三、等号两端必需要有空格
记住在单括号和双括号的写法的区别,测试一下
条件表达式6种写法:if,while 语法1: test <测试表达式> 语法2: [ <测试表达式> ] #两端有空格 语法3:[[ <测试表达式> ]] #两端有空格 语法4:((<测试表达式>)) #不须要空格 语法5:(命令表达式) 语法6:`命令表达式` 编程语法: [ <测试表达式> ] && 命令1 若是前面表达式成功,那么就执行后面命令。 [ <测试表达式> ] || 命令1 若是前面表达式失败,那么就执行后面命令。 [ <测试表达式> ] && { 命令1 命令2 命令3 } 若是前面表达式成功,那么就执行后面命令。 [ <测试表达式> ] && 命令1 || 命令2 若是前面表达式成功,那么就执行命令1,不然执行命令2。 [ <测试表达式> ] && { 命令1 命令2 }||{ 命令3 命令4 } 若是前面表达式成功,那么就执行命令1,2,不然执行命令3,4。 <测试表达式>有哪些: 文件测试表达式: 为何须要文件测试表达式? 操做一个对象,就要看对象条件是否知足,不然不要操做。 1、常见功能 2、实践 3、企业应用:启动脚本中的应用。 字符串测试表达式 [ -n "字符串" ] 字符串长度[不]为0,表达式为真。 not zero。 [ -z "字符串" ] 字符串长度为0,表达式为真。 zero。 [ "字符串1" == "字符串2" ] 两个字符串相同则为真。 [ "字符串1" !== "字符串2" ] 两个字符串不相同则为真。 注意: 1、字符串就用双引号 2、等号能够用一个或者两个。 3、=号两端必需要有空格。 实践: [root@web01 ~]# [ -n "oldboy" ] && echo 1 || echo 0 1 [root@web01 ~]# [ -z "oldboy" ] && echo 1 || echo 0 0 [root@web01 ~]# char="oldboy" [root@web01 ~]# [ -z "$char" ] && echo 1 || echo 0 0 [root@web01 ~]# unset char [root@web01 ~]# [ -z "$char" ] && echo 1 || echo 0 1 [root@web01 ~]# [ "dd" == "dd" ] && echo 1 || echo 0 1 [root@web01 ~]# [ "dd" == "ff" ] && echo 1 || echo 0 0 [root@web01 ~]# [ "dd" = "ff" ] && echo 1 || echo 0 0 [root@web01 ~]# [ "dd" != "ff" ] && echo 1 || echo 0 1 [root@web01 ~]# [ "dd" != "dd" ] && echo 1 || echo 0 0 改造上面的四则运算的脚本 企业应用: [root@db03 scripts]# cat yunsuan1.sh #!/bin/bash ############################################################## # File Name: yunsuan.sh # Version: V1.0 # Author: oldboy # Organization: www.oldboyedu.com # Created Time : 2018-05-30 09:03:10 # Description: ############################################################## #!/bin/bash read -p "pls input two num:" a b
# b没有值,确定是没有输入或者没有输入2个 if [ -z "$b" ] then echo "请输入两个数" exit 1 fi
# 判断是否是数字
expr $a + $b + 1 &>/dev/null if [ $? -ne 0 ] then echo "Usage:$0 num1 num2" exit 1 fi echo "a-b=$(($a-$b))" echo "a+b=$(($a+$b))" echo "a*b=$(($a*$b))" echo "a/b=$(($a/$b))" echo "a**b=$(($a**$b))" echo "a%b=$(($a%$b))" 整数测试表达式: 小题:使用read的交互方式,来比较两个整数的大小。 分析: 1、要求整数 2、2个数 3、比较大小 大于 等于 小于 [root@web01 scripts]# cat com1.sh #!/bin/bash read -p "请输入两个整数:" a b #1.判断是否是输入两个数 [ -z "$b" ] &&{ echo "请输入两个整数" exit 1 } #2.判断整数 expr $a + $b + 1 &>/dev/null [ $? -ne 0 ] &&{ echo "请输入两个整数" exit 2 } #3.判断是否大于 [ $a -gt $b ] &&{ echo "$a>$b" exit 0 } #4.判断是否等于 [ $a -eq $b ] &&{ echo "$a=$b" exit 0 } #5.判断是否小于 echo "$a<$b" [root@db03 scripts]# cat comp.sh #!/bin/bash ############################################################## # File Name: comp.sh # Version: V1.0 # Author: oldboy # Organization: www.oldboyedu.com # Created Time : 2018-05-30 11:36:19 # Description: ############################################################## read -p "Pls input two num:" a b #1.第一关判断传入的内容都是整数 expr $a + $b + 100 &>/dev/null [ $? -ne 0 ] &&{ echo "Usage:$0 num1 num2" exit 1 } #2.第二关输入两个数 [ -z "$b" ] &&{ echo "Usage:$0 num1 num2" exit 2 } #3.比较大小 [ $a -gt $b ] && { echo "$a>$b" exit 0 } [ $a -eq $b ] && { echo "$a=$b" exit 0 } echo "$a<$b" exit 0 ==============升级使用if [root@db03 scripts]# cat comp.sh #!/bin/bash ############################################################## # File Name: comp.sh # Version: V1.0 # Author: oldboy # Organization: www.oldboyedu.com # Created Time : 2018-05-30 11:36:19 # Description: ############################################################## read -p "Pls input two num:" a b #1.第一关判断传入的内容都是整数 expr $a + $b + 100 &>/dev/null [ $? -ne 0 ] &&{ echo "Usage:$0 num1 num2" exit 1 } #2.第二关输入两个数 [ -z "$b" ] &&{ echo "Usage:$0 num1 num2" exit 2 } #3.比较大小 if [ $a -gt $b ] then echo "$a>$b" elif [ $a -eq $b ] then echo "$a=$b" else echo "$a<$b" fi 逻辑测试表达式 ! 非 && -a 而且 || -o 或者 []中 使用 -a -o [[]]或(())里面 使用&& || [] [[]] (()) 这些符号之间链接 使用&& || make && make install ==================== [root@db03 scripts]# [ 1 -eq 1 -a -f /etc/hosts ] && echo 1 || echo 0 1 [root@db03 scripts]# [ 1 -eq 2 -a -f /etc/hosts ] && echo 1 || echo 0 0 [root@db03 scripts]# [ 1 -eq 2 && -f /etc/hosts ] && echo 1 || echo 0 -bash: [: missing `]' 0 [root@db03 scripts]# [[ 1 -eq 2 && -f /etc/hosts ]] && echo 1 || echo 0 0 [root@db03 scripts]# [ 1 -eq 2 ] && [ -f /etc/hosts ] && echo 1 || echo 0 [root@db03 scripts]# [ -f /etc/hosts ] && echo 1 || echo 0 1 [root@db03 scripts]# [ ! -f /etc/hosts ] && echo 1 || echo 0 0 小题:若是/tmp/oldboy.sh是普通文件,而且可执行,就执行改脚本。 file="/tmp/oldboy.sh" if [ -f $file ] && [ -x $file ] then bash $file fi 1. 单分支结构 第一种语法: if <条件表达式> then 指令 fi 第二种语法: if <条件表达式>; then 指令 fi 若是 <你有房> 那么 我就嫁给你 果如 if条件句的双分支结构语法为: if <条件表达式> then 指令集1 else 指令集2 fi 若是 <你有房> 那么 我就嫁给你 不然 我再考虑下 果如 多分支: if <条件表达式1> then 指令1... elif <条件表达式2> then 指令2... elif <条件表达式3> then 指令3... else 指令4... fi 范例7_2:开发Shell脚本判断系统剩余内存的大小,若是低于100MB就邮件报警给系统管理员, 而且将脚本加入系统定时任务,即每3分钟执行一次检查。 分析思路: 1、取内存 free -m|awk 'NR==3{print $NF}' 2、发邮件 mail -s "主题" 邮件地址 </etc/hosts echo ""|mail -s "主题" 邮件地址 3、开发脚本判断发邮件 full="内存充足。" leak="内存不足。" free=`free -m|awk 'NR==3{print $NF}'` if [ $free -lt 1000 ] then echo "$leak"|tee /tmp/mail.log mail -s "$leak`date`" 31333741-@qq.com </tmp/mail.log else echo "$full" fi 4、加入定时任务 [root@db03 scripts]# crontab -l|tail -2 ########### */3 * * * * /bin/sh /server/scripts/judge.sh >/dev/null 2>&1 课后练习:开发Shell脚本判断系统根分区剩余空间的大小,若是低于1000MB报警空间不足, 若是低于500M,就报警空间严重不足,最后把结果邮件发给系统管理员, 而且将脚本加入系统定时任务,即每3分钟执行一次检查。 预习: 函数 case for while
Shell编程实战:第一模块前六节复习:Shell编程基础 01-第一章:如何学好shell编程。 必备基础: 1)熟练vim编辑器,.vimrc配置。 2)120个左右Linux命令。(跟老男孩学习Linux运维:核心命令实战) 3)网络服务,rsync,nfs,lamp,lnmp,ltmp,keepalived,lvs 如何学好: 1、锻炼编程思惟
好比要先有大纲 第一章 1.1 1.1.1 1.1.2 第二章 2.1 2.1.1 2.1.2 2、多练,多思考,不要拿来主义。 3、有一本教科书。跟老男孩学习Linux运维:Shell编程实战 02-第二章:Shell基础入门 什么是shell 什么是shell脚本 shell脚本的创建 #!/bin/bash #### shell脚本的执行 4种方式: 1)bash/sh oldboy.sh #推荐使用 2)source/. oldboy.sh ***** 3)sh/bash<oldboy.sh 4)./oldboy.sh或/server/scripts/oldboy.sh #必需要有执行权限。 Shell的执行过程 oldboy.sh: pwd ls oldgirl.sh #子shell ls oldgirl.sh & 放到后台执行。 并行,执行的同时,也执行下面的额ls 重点也是难点 source/. oldgirl.sh 至关于子Shell和父Shell至关于在一个shell里运行。 03-第三章 变量基础 1、什么是变量? oldboy="I am oldboy" oldboy是变量名,= 是赋值符号,"I am oldboy"是变量的内容。 OldboyAge oldboyAge #推荐。 oldboy_age 2、变量类型,shell里面是弱类型 decalre -i A #定义一个整形,通常没有这种需求 3、变量分类 环境变量(全局变量) 特色:大写 全局生效 1)系统的环境变量 PS1,PATH,LANG 直接用。 2)自定义环境变量 export OLDBOY=1 OLDBOY=1 export OLDBOY decalre OLDBOY=1 查看: env/set echo $变量名 取消: unset 变量名 普通变量(局部变量) 局部生效: oldboy="I am oldboy" oldboy是变量名,=是赋值符号,"I am oldboy"是变量的内容。 变量名: OldboyAge oldboyAge #推荐。 oldboy_age = 两边不能有空格 变量内容: 4种方式 a=test #不加引号,也会解析变量,推荐连续数字用此方法。 a='test' #所见即所得。 a="test" #默认双引号,解析变量。 a=`date` #解析一个命令结果。就用``或$()。 输出变量: $oldboy_age ${oldboy_age}dddd 04-第四章 变量的扩展 1)特殊位置变量 $0 ***** 企业应用-脚本的结尾 $1,$2,$n ***** $# ***** 获取参数的个数 $* 两个的相同点和不一样点 $@ 2)特殊状态变量 $? ***** $$ 进程号 $!上一个脚本的进程 $_ 上一个脚本的最后一个参数 至关于 esc+点 3)变量的子串 ${oldboy} ${#oldboy} wc -L ,expr length "$oldboy",awk '{print length }' ${oldboy:2} ${oldboy:2:2} ${oldboy#word} ${oldboy##word} ${oldboy%word} ${oldboy%%word} ${oldboy/dd/ff} ${oldboy//dd/ff} 4)变量特殊扩展 result=${oldboy:-word} # 推荐 **** result=${oldboy:=word} result=${oldboy:?word} result=${oldboy:+word} 霸道 第五章 变量的数值计算 整数: (()) 推荐 let 推荐 $[] expr declare declare -i a=4+3 echo $a 小数: bc 推荐加减 awk 乘除推荐 expr: 1)判断是否为整数。 2)扩展名 。忘记判断,记忆窍门 vim ·which ssh-copy-id· 3)取字符串长度 变量的定义: 1)a=1 2)传参 3)read读入 read -t 10 -p "输入提示:" a 用途:菜单选择,和用户交互
第六章 条件测试与比较 6种: [] #推荐 [[]] test (()) (命令) `命令` 等价if单分支 []&&{ dddd } 等价if双分支 []&&{ dddd }||{ ddd } =================================== [ -f /etc/hosts ] || exit 5 经常使用的推荐用法,简简洁,命令多的时候,用if比较好 make && make install ================================= if,whlie 当作一个条件判断。 文件、字符、整数 测试 逻辑符
均可以用man test 找到
章节一
试题1:用source执行脚本和用bash执行Shell脚本的区别是什么? 考试题2:如何自定义环境变量? 考试题3:定义变量内容,不加引号、单引号、双引号、反引号结果有什么不一样?应该怎么用? 考试题4:请分别说出2个以上用于整数运算特殊符号或命令,以及适合小数运算的命令。 考试题5:写出特殊变量对应的意义及应用 $0、$n、$#、$*、$@、$?、$$、$!、$_ 考试题6:写出下面特殊变量扩展的意义 ${oldboy}、${#oldboy}、${oldboy:offset:length}、${oldboy#word}、${oldboy##word}、${oldboy%word}、${oldboy%%word}、${oldboy/pattern/string}、${oldboy//pattern/string}、${oldboy:-word} 考试题7:在条件测试与表达式中,[]和[[]]有何区别? 考试题8:说出适合在[]以及test中整数比较的特殊运算符号? 考试题九、输出下面菜单 1.install MySQL 2.install Tomcat 3.exit 当用户选择对应的数字就开始安装对应的服务(可echo输出替代),须要对用户输入的数字进行判断是否为整数(用条件测试表达式实现)。 考试题十、使用read读入方式比较两个整数大小(用条件表达式实现)。
章节二
考试题1:开发Shell脚本判断系统根分区剩余空间的大小,若是低于1000MB就提示不足,不然提示充足。 考试题2:分别使用变量定义、read读入及脚本传参方式实现比较2个整数的大小。 考试题3:打印一个菜单以下,当用户选择对应的数字时,就执行对应项的应用,最好对用户的输入进行是否为整数判断。 1.install lamp 2.install lnmp 3.exit 考试题4:经过脚本传参的方式,检查Web网站URL是否正常(要求主体使用函数)。 考试题5:利用case语句开发Rsync服务启动中止脚本,并能经过chkconfig实现开机自启动。 考试题6:猜数字游戏。首先让系统随机生成一个数字,给这个数字定一个范围(1-60),让用户输入猜的数字,对输入进行判断,若是不符合要求,就给予高或低的提示,猜对后则给出猜对用的次数,请用while语句实现。 考试题7:分析nginx访问日志(自备),把日志中每行的访问字节数对应字段数字相加,计算出总的访问量。给出实现程序,请用while循环实现。 考试题8:计算从1加到100之和(要求用for和while,至少给出两种方法)。 考试题9:利用bash for循环打印下面这句话中字母数不大于6的单词(某企业面试真题)。I am oldboy teacher welcome to oldboy training class 考试题10:使用read读入方式比较两个整数大小,要求对用户输入的内容严格判断是否为整数,是否输入了两个数字。