“ ”双引 引总体
“a b c” != a b c
abc == “abc” 之后最好加“”,防止出现错误express
‘’ 单引 引总体,屏蔽特殊符号 ‘abc’
[root@localhost test]# a=12
[root@localhost test]# echo "$a RMB"
12 RMB
[root@localhost test]# echo '$a RMB'
$a RMBvim
\ 把它右边的符号屏蔽掉
[root@localhost test]# a=12
[root@localhost test]# echo "\$a RMB"
$a RMB
[root@localhost test]# echo "\$a $a $a $a"
$a 12 12 12bash
echo a b c 这是不一样的 计算机理解是a,b,c
echo 'abc' 计算机理解是a b c app
看不清有几个文件 llless
[root@localhost ~]# mkdir test
[root@localhost ~]# cd /test
-bash: cd: /test: 没有那个文件或目录
[root@localhost ~]# cd test
[root@localhost test]# touch "a b c"
[root@localhost test]# ls
a b c
[root@localhost test]# rm -rf a b c
[root@localhost test]# ls
a b c
[root@localhost test]# rm -rf "a b c"
[root@localhost test]# lstcp
``反引 引用的是命令,提取命令的结果ide
计划任务:每周五对日志备份一次,备份到/root
crontab -e //edit
11 03 */5 tar -zcf /root/log.tar.gz /var/log 工具
( 5 每周五每分都在备份 ,必定要给个具体时间
#一样的文件名字会覆盖# 文件名要是变量 ,文件的后缀最好是时间)oop
date +s 修改时间
--set=STRING
set time described by STRING测试
[root@localhost test]# date +"%Y%m%d"
20170409
date +"%Y%m%d"
=20170409
11 03 */5 tar -zcf log-date +"%Y%m%d"
.tar.gz /var/log
log -(添加识别的关键字)
[root@localhost test]# tar -zcf log-date +"%Y%m%d"
.tar.gz /var/log
tar: 从成员名中删除开头的“/”
[root@localhost test]# ls
20170409.tar.gz log-20170409.tar.gz
变量
写脚本,写定义变量,但不赋值,执行脚本再赋值
read -p "提示信息" 变量
read 变量
[root@localhost test]# read abc
yy()
[root@localhost test]# echo $abc
yy
read -p "请输入用户名:" user (""中的内容是提示符)
写一个脚本,提示用户输入用户和密码
根据用户的输入建立帐户和密码
[root@localhost ~]# vim test1.sh
#!/bin/bash
read -p "请输入用户名:" user
useradd $user
read -p "请输入密码:" pass
echo "$pass" | passwd --stdin $user
[root@localhost ~]# bash test1.sh
请输入用户名:sanpao
请输入密码:456
更改用户 sanpao 的密码 。
passwd:全部的身份验证令牌已经成功更新。
#密码明文显示#
stty -echo 不显示
stty echo 回显
#在某个位置不打开回显,必定要再打开。不然之后会很麻烦。
不显示密码
#!/bin/bash
read -p "请输入用户名:" user
stty -echo
read -p "请输入密码:" passwd
stty echo
useradd $user
echo $passwd | passwd --stdin $user
1.变量
全局变量 (export 输出)
[root@localhost ~]# export a=12
[root@localhost ~]# bash
[root@localhost ~]# bash
[root@localhost ~]# echo $a
12
[root@localhost ~]# b=12
[root@localhost ~]# export b
[root@localhost ~]# bash
[root@localhost ~]# bash
[root@localhost ~]# echo $b
12
本身写脚本局部变量,系统自带的全局变量
局部变量
Top
NSD SHELL DAY02
1.整数运算
expr 数字 数学符号 数字 (很差用)
[root@localhost ~]# expr 1 + 2
3
[root@localhost ~]# expr 1+ 2
expr: 语法错误
支持+ - * / %【取余数】求模运算
[root@localhost ~]# expr 5 % 3
2
$((数字符号数字)) 或者 $[数字符号数字] 没有回显功能
[root@localhost ~]# echo $((12))
2
[root@localhost ~]# echo $[32]
6
[root@localhost ~]# a=12
[root@localhost ~]# b=2
[root@localhost ~]# echo $[a+b]
14
let 数字符号数字 不带回显功能
[root@localhost ~]# let c=a+b
[root@localhost ~]# echo $c
14
++【不会单独用,会跟动做一块儿用,作计数器】 -- ===>>每次只是+1或是-1
+= -= *= /= ===>>等于号后面赋予变量的值
1+2 2元运算
x++ 1元运算
a=2
let a++ # a=a+1
[root@localhost ~]# a=2
[root@localhost ~]# let a++
[root@localhost ~]# echo $a
3
[root@localhost ~]# let a++
[root@localhost ~]# echo $a
4
+=
a=2
let a+=2 a=a+2
[root@localhost ~]# a=2
[root@localhost ~]# let a+=2
[root@localhost ~]# echo $a
4
[root@localhost ~]# let a+=2
[root@localhost ~]# echo $a
6
[root@localhost ~]# let a+=6
[root@localhost ~]# echo $a
12
[root@localhost ~]# let a-=1
[root@localhost ~]# echo $a
11
[root@localhost ~]# let a-=1
[root@localhost ~]# echo $a
10
[root@localhost ~]# let a*=2
[root@localhost ~]# echo $a
20
[root@localhost ~]# let a/=10
[root@localhost ~]# echo $a
2
2.小数运算
%【取余数】求模运算 #余数必定会小于被除数#
bc计算器
交互
非交互
需告知小数点后留有几位scale
[root@localhost ~]# echo "scale=2;3.000000005/2.15" | bc
1.39
[root@localhost ~]# echo "scale=2;3/10" | bc
.30
[root@localhost ~]# echo "scale=4;3.5*2.81" | bc
9.835
man text
SYNOPSIS
test EXPRESSION
test
[ EXPRESSION ] [ ] [ OPTION
3.测试 更加智能
test 表达式
[ 表达式 ] 1)字串 2)数字 3)文件、目录
能测试哪些东西
1.字符串测试 【-z 检查变量的值是否设置】
[ -z $变量 ]
-z STRING 字串
the length of STRING is zero 测字串是否为空
-z 字符串的值为空
-n 字符串的值不为空(至关于! -z )
[root@localhost ~]# a=12
[root@localhost ~]# [ -z $a ]
[root@localhost ~]# echo $?
1
[root@localhost ~]# [ -z $ttttttt ]
[root@localhost ~]# echo $?
0
同一行打多个命令【多个命令,最好从后面往前分析】
1.&& 而且 A && B 【而且】
只有A成功了,才会去执行B,B不必定会成功;若A不成功,则B不执行。
给定的条件必须都成立,整个测试结果才为真。
2.|| 或者 A || B
如A成功,则不执行B。如A不成功,则执行B。
只要其中的一个条件成立,则整个测试结果为真。
3.分号; A;B 无论A成不成功都执行B
A && B | C && D
A确定会执行
[root@localhost ~]# [ -z $rrrrrr ] && echo yes || echo no
yes
[root@localhost ~]# [ -z $a ] && echo yes || echo no
no
A && B A成功=》B
A || B
[ -z $ttttttt ] && echo y || echo n
A && B || C
写脚本,若是用户不输入用户名,则脚本退出
-s silent 有回显
#!/bin/bash
read -p "请输入用户名:" user
[ -z $user ] && echo "您没有输入用户名" && exit
stty -echo
read -s -p "请输入密码:" password 【-s选项可以使read命令中输入的数据不显示在监视器上(实际上数据是显示的,只是read命令将文本颜色设置成与背景相同的颜色)】
stty echo
[ -z $password ] && echo "您没有输入密码" && exit
useradd $user
echo $password | passwd --stdin $user
能测试哪些
1.字符串
[ -z $abc ]是否为空 【答案取反】
[ ! -z $abc ] 是否非空 【答案正常】
a=12
[ ! -z $a ] 对,不是空
$?(对,错)
[root@localhost ~]# a=12
[root@localhost ~]# [ -z $a ] $a是空的吗?
[root@localhost ~]# echo $?
1 错,$a不是空的
[root@localhost ~]# [ -z $zz ] $zz
[root@localhost ~]# echo $?
0 $zz
[root@localhost ~]# [ ! -z $a ]
[root@localhost ~]# echo $?
0
测试基本不用常量
[ a == b ] 是否相同
[ a != b ] 是否不一样
[root@localhost ~]# [ $USER == root ]
[root@localhost ~]# echo $?
0
2.数字
等于 equal eq
不一样等于 not equal ne 【纳特】
小于 less than lt
小于等于 less equal le
大于 greater than gt
大于等于 greater equal ge
写脚本 脚本自动生成10之内随机数,让用户猜是多少
脚本自动判断,对和错
RANDOM 随机生成数
猜 read
#! /bin/bash
num=$[RANDOM%10] 将值固定死!
read -p "我有一个随机数,让你猜:" guest
[ $num -eq $guest ] && echo "恭喜你,答对了。" || echo "哎哟,错了。"
写脚本 脚本自动生成10之内随机数,让用户猜是多少
脚本判断,给出提示大于,小于,等于
vim text.sh
vim
3.文件或目录测试
[ -d 文件或目录 ] 测试是否存在且为目录 directory
[ -f 文件或目录 ] 测试是否存在且为文件 file
[ -e 文件或目录 ] 测试是否存在 exist
[ -s 文件 ] 测试是大小是否大与0 size
[ -r 文件 ]
[ -w 文件 ]
[ -x 文件 ]
谁执行的脚本测谁
检测目录是否存在,不存在自动建立abc
mount -o loop ISO /abc
#!/bin/bash
[ -d /nmt ] || mkdir /mnt
mount -o loop /ISO/rhel-server-7.2-x86_64-dvd.iso /mnt
[ -e 找7.2中随机一个文件是否存在 ]
每分钟测试当前登录用户数量,是否大于3
若是大于3,则发送邮件报警
1)当前几我的登录
wc=word count 字数统计 -l = --line
-c = --char 字符
[root@room4pc09 桌面]# who
root :0 2017-04-10 07:33 (:0)
root pts/1 2017-04-10 14:46 (:0)
root pts/2 2017-04-10 08:26 (:0)
root pts/3 2017-04-10 17:18 (:0)
[root@room4pc09 桌面]# who | wc -l
4
vim test.sh
num=who | wc -l
##注意反引号
[ $num -gt 3 ] && mail -s 标题 root < 文件
crondtab -e
计划任务,每分钟执行该脚本
#!/bin/bash
user=who |wc -l
[ $user -gt 3 ] && mail -s Error root < /etc/passwd
发送给root,若是公司连网,也能够发送root@163.com【发送给本身的邮箱】
crondtab -e
if语法格式
1.单分支【对】
if [ ];then
命令
fi
也能够:
if [ ]
then
命令
fi
[root@localhost ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
/dev/mapper/rhel-root 50G 3.0G 48G 6% /
devtmpfs 482M 0 482M 0% /dev
tmpfs 497M 0 497M 0% /dev/shm
tmpfs 497M 7.0M 490M 2% /run
tmpfs 497M 0 497M 0% /sys/fs/cgroup
/dev/mapper/rhel-home 38G 33M 38G 1% /home
/dev/vda1 497M 158M 340M 32% /boot
tmpfs 100M 0 100M 0% /run/user/0
【写脚本最好不用-h!!给人看的加-h】
[root@localhost ~]# df
文件系统 1K-块 已用 可用 已用% 挂载点
/dev/mapper/rhel-root 52403200 3091040 49312160 6% /
devtmpfs 492924 0 492924 0% /dev
tmpfs 508456 0 508456 0% /dev/shm
tmpfs 508456 7164 501292 2% /run
tmpfs 508456 0 508456 0% /sys/fs/cgroup
/dev/mapper/rhel-home 39245084 33152 39211932 1% /home
/dev/vda1 508588 160796 347792 32% /boot
tmpfs 101692 0 101692 0% /run/user/0
如何直接取其中一行 df 目录 或 df | grep "root"
[root@localhost ~]# df /
文件系统 1K-块 已用 可用 已用% 挂载点
/dev/mapper/rhel-root 52403200 3091032 49312168 6% /
[root@localhost ~]# df /boot
文件系统 1K-块 已用 可用 已用% 挂载点
/dev/vda1 508588 160796 347792 32% /boot
[root@localhost ~]# df | grep "root"
/dev/mapper/rhel-root 52403200 3091020 49312180 6% /
[root@localhost ~]# nu=49312180:
[root@localhost ~]# if [ $nu -lt 40000 ];then
echo Error
fi
#!/bin/bash
nu=49312180
if [ $nu -le 4000 ];then
echo Error
fi
若是磁盘容量小于等于4000,则报警!
2.双分支 【对,错】【非对即错】
if [ ];then
命令
else
命令
fi
###判断httpd是否开启,若是开启提示YES,没有开启提示NO###
systemctl status
1.看端口:80
[root@localhost httpd]# systemctl restart httpd
[root@localhost httpd]# netstat -anptu | grep 80
tcp6 0 0 :::80 :::* LISTEN 9035/httpd
[ -z $a ] //当$a取值太多的话,会显示错误,这时必定要用“”引上, 即[ -z "$a" ]
rpm -
[root@localhost ~]# vim test-httpd80.sh
#!/bin/bash
netstat -ntulp | grep http > /dev/null
if [ $? -eq 0 ] //若是[ $? == 0 ] ,会把==两端的字符串看成两个数字进行比较。
then
echo yes
else
echo no
fi
2.看pid (/var/run/)
[root@localhost ~]# vim test-httpd.sh
:#!/bin/bash
if [ -f /var/run/httpd/httpd.pid ]
then echo "YES"
else echo "NO"
fi
netstat -ntulp | grep httpd
###./test.sh 192.168.4.5(参数)###
脚本自动判断该IP是否能ping通。
vim test-ping.sh
#!/bin/bash
read -p "请输入IP地址:" IP
ping -c 2 $IP &> /dev/null //-c count次数
if [ $? -eq 0 ]
then
echo "通了。"
else
echo "不通。"
fi
~
[root@localhost ~]# ping -c 2 -i 0.1 192.168.4.1 //-i 单位是秒。间隔0.1秒。
PING 192.168.4.1 (192.168.4.1) 56(84) bytes of data.
64 bytes from 192.168.4.1: icmp_seq=1 ttl=64 time=0.044 ms
64 bytes from 192.168.4.1: icmp_seq=2 ttl=64 time=0.053 ms
--- 192.168.4.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 100ms
rtt min/avg/max/mdev = 0.044/0.048/0.053/0.008 ms
3.多分支(多种可能性)
if [ ];then
命令
elif [ ];then
命令
elif [ ];then
命令
else 【不然,其余的意思】
命令
fi
read -p "请输入一个字母:" key
if [ $key == a ];then
echo "你输入的是a"
if [ $key == b ];then
echo "你输入的是b"
if [ $key == c ];then
echo "你输入的是c"
else
echo "你输入的不是abc。"
fi
【常见错误】
##echo $[ ] 这个运算中不能有小数点。有小数点的数只能在bc中。
[root@localhost ~]# [ abc ]
[root@localhost ~]# echo $?
0
案例1:Shell中的数值运算 案例2:条件测试操做 案例3:使用if选择结构
1 案例1:Shell中的数值运算
1.1 问题
本案例要求熟悉Linux Shell环境的特色,主要练习如下操做:
使用expr、$[ ]、let等整数运算工具:定义变量X=1234,而后计算X与78的四则运算及求模结果 使用bc实现小数运算操做:以交互方式计算12.34与56.78的四则运算结果,另外再以非交互方式重复上述计算,最多显示4位小数
1.2 步骤
实现此案例须要按照以下步骤进行。
步骤一:整数运算工具
1)使用expr命令
乘法操做应采用 * 转义,避免被做为Shell通配符;参与运算的整数值与运算操做符之间须要以空格分开,引用变量时必须加$符号。
首先定义变量X=1234,而后分别计算与78的加减乘除和求模运算结果:
[root@svr5 ~]# X=1234 //定义变量X [root@svr5 ~]# expr $X + 78 //加法 1312 [root@svr5 ~]# expr $X - 78 //减法 1156 [root@svr5 ~]# expr $X \* 78 //乘法,操做符应添加\转义 96252 [root@svr5 ~]# expr $X / 78 //除法,仅保留整除结果 15 [root@svr5 ~]# expr $X % 78 //求模 64
2)使用$[ ]或$(())表达式
乘法操做*无需转义,运算符两侧能够无空格;引用变量可省略 $ 符号;计算结果替换表达式自己,可结合echo命令输出。
一样对于变量X=1234,分别计算与78的加减乘除和求模运算结果:
[root@svr5 ~]# X=1234 [root@svr5 ~]# echo $[X+78] 1312 [root@svr5 ~]# echo $[X-78] 1156 [root@svr5 ~]# echo $[X*78] 96252 [root@svr5 ~]# echo $[X/78] 15 [root@svr5 ~]# echo $[X%78] 64
3)使用let命令
expr或$[]、$(())方式只进行运算,并不会改变变量的值;而let命令能够直接对变量值作运算再保存新的值。所以变量X=1234,在执行let运算后的值会变动;另外,let运算操做并不显示结果,可是能够结合echo命令来查看:
[root@svr5 ~]# X=1234 [root@svr5 ~]# let X+=78 ; echo $X 1312 [root@svr5 ~]# let X-=78 ; echo $X 1234 [root@svr5 ~]# let X*=78 ; echo $X 96252 [root@svr5 ~]# let X/=78 ; echo $X 1234 [root@svr5 ~]# let X%=78 ; echo $X 64
步骤二:小数运算工具
1)bc交互式运算
先执行bc命令进入交互环境,而后再输入须要计算的表达式。以计算小数12.34与5.678的四则运算为例,相关操做以下:
[root@svr5 ~]# 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'. 12.34+56.78 //加法 69.12 12.34-56.78 //减法 -44.44 12.34*56.78 //乘法 700.66 12.34/56.78 //除法 0 quit //退出交互计算器 [root@svr5 ~]#
2)bc非交互式运算
将须要运算的表达式经过管道操做交给bc运算。注意,小数位的长度可采用scale=N限制,除此之外也受参与运算的数值的小数位影响。以计算小数12.34与5.678的四则运算为例,相关操做以下:
[root@svr5 ~]# echo 'scale=4;12.34+5.678' | bc 18.018 [root@svr5 ~]# echo 'scale=4;12.34-5.678' | bc 6.662 [root@svr5 ~]# echo 'scale=4;12.34*5.678' | bc 70.0665 [root@svr5 ~]# echo 'scale=4;12.34/5.678' | bc 2.1733
2 案例2:条件测试操做
2.1 问题
本案例要求参考PPT上的示例,分别练习如下条件测试操做:
字符串匹配 比较整数值的大小 识别文件/目录的状态 多个条件/操做的逻辑组合
2.2 步骤
实现此案例须要按照以下步骤进行。
步骤一:条件测试的基本用法
1)语法格式
使用“test 表达式”或者[ 表达式 ]均可以,表达式两边至少要留一个空格。
条件测试操做自己不显示出任何信息。测试的条件是否成立主要体如今命令执行后的返回状态(即 $?),因此能够在测试后查看变量$?的值来作出判断,或者结合&&、||等逻辑操做显示出结果(或做其余操做) 。
步骤二:字符串测试
1)== 比较两个字符串是否相同
检查当前用户是否为root。
当root用户执行时:
[root@svr5 ~]# [ $USER == "root" ] //测试 [root@svr5 ~]# echo $? //查看结果0为对,非0为错
当普通用户执行时:
[zengye@svr5 ~]$ [ $USER == "root" ] NO [zengye@svr5 ~]$ echo $?
2)!= 比较两个字符串是否不相同
检查当前用户,若是不是root。
当普通用户执行时:
[zengye@svr5 ~]$ [ $USER != "root" ]
当root用户执行时:
[root@svr5 ~]# [ $USER != "root" ]
3)-z 检查变量的值是否未设置(空值)
[root@svr5 ~]# var1="Tarena" ; var2="" [root@svr5 ~]# [ -z "$var1" ] && echo "空值" || echo "非空值" 非空值 [root@svr5 ~]# [ -z $var2 ] && echo "空值" || echo "非空值" 空值 //变量var2已设置,但无任何值,视为空 [root@svr5 ~]# [ ! -z $var1 ] //测试var1是否为非空
步骤三:整数值比较
参与比较的必须是整数(能够调用变量),比较非整数值时会出错:
[root@svr5 ~]# A=20.4 [root@svr5 ~]# [ $A -gt 10 ] //不支持小数比较 -bash: [: 20.4: integer expression expected
1)-eq 比较两个数是否相等。
[root@svr5 ~]# X=20 //定义一个测试变量 [root@svr5 ~]# [ $X -eq 20 ] && echo "相等" || echo "不相等" 相等 [root@svr5 ~]# [ $X -eq 30 ] && echo "相等" || echo "不相等" 不相等
2)-ne 比较两个数是否不相等。
[root@svr5 ~]# [ $X -ne 20 ] && echo "不等于" || echo "等于" 等于 [root@svr5 ~]# [ $X -ne 30 ] && echo "不等于" || echo "等于" 不等于
3)-gt 比较前面的整数是否大于后面的整数。
[root@svr5 ~]# [ $X -gt 10 ] && echo "大于" || echo "否" 大于 [root@svr5 ~]# [ $X -gt 20 ] && echo "大于" || echo "否" 否 [root@svr5 ~]# [ $X -gt 30 ] && echo "大于" || echo "否" 否
4)-ge 比较前面的整数是否大于或等于后面的整数。
[root@svr5 ~]# [ $X -ge 10 ] && echo "大于或等于" || echo "否" 大于或等于 [root@svr5 ~]# [ $X -ge 20 ] && echo "大于或等于" || echo "否" 大于或等于 [root@svr5 ~]# [ $X -ge 30 ] && echo "大于或等于" || echo "否" 否
5)-lt 比较前面的整数是否小于后面的整数。
[root@svr5 ~]# [ $X -lt 10 ] && echo "小于" || echo "否" 否 [root@svr5 ~]# [ $X -lt 20 ] && echo "小于" || echo "否" 否 [root@svr5 ~]# [ $X -lt 30 ] && echo "小于" || echo "否" 小于
6)-le 比较前面的整数是否小于或等于后面的整数。
[root@svr5 ~]# [ $X -le 10 ] && echo "小于或等于" || echo "否" 否 [root@svr5 ~]# [ $X -le 20 ] && echo "小于或等于" || echo "否" 小于或等于 [root@svr5 ~]# [ $X -le 30 ] && echo "小于或等于" || echo "否" 小于或等于
7)提取当前登陆的用户数,比较是否超过5。
[root@svr5 ~]# who | wc -l //确认已登陆的用户数 4 [root@svr5 ~]# N=$(who | wc -l) //赋值给变量N [root@svr5 ~]# [ $N -gt 5 ] && "超过了" || echo "没超过" 没超过
上述赋值给变量N及与5比较的操做,能够简化为以下形式:
[root@svr5 ~]# [ $(who | wc -l) -gt 5 ] && "超过了" || echo "没超过" 没超过
步骤四:识别文件/目录的状态
1)-e 判断对象是否存在(不论是目录仍是文件)
[root@svr5 ~]# [ -e "/usr/src/" ] && echo "存在" || echo "不存在" 存在 [root@svr5 ~]# [ -e "/etc/fstab" ] && echo "存在" || echo "不存在" 存在 [root@svr5 ~]# [ -e "/home/nooby" ] && echo "存在" || echo "不存在" 不存在
2)-d 判断对象是否为目录(存在且是目录)
[root@svr5 ~]# [ -d "/usr/src/" ] && echo "是目录" || echo "不是目录" 是目录 [root@svr5 ~]# [ -d "/etc/fstab" ] && echo "是目录" || echo "不是目录" 不是目录 [root@svr5 ~]# [ -d "/home/nooby" ] && echo "是目录" || echo "不是目录" 不是目录
3)-f 判断对象是否为文件(存在且是文件)
[root@svr5 ~]# [ -f "/usr/src/" ] && echo "是文件" || echo "不是文件" 不是文件 [root@svr5 ~]# [ -f "/etc/fstab" ] && echo "是文件" || echo "不是文件" 是文件 [root@svr5 ~]# [ -f "/home/nooby" ] && echo "是文件" || echo "不是文件" 不是文件
4)-r 判断对象是否可读
此测试对root用户无效,不管文件是否设置r权限,root均可读:
[root@svr5 ~]# cp install.log /tmp/rtest.txt //复制一个文件作测试 [root@svr5 ~]# chmod -r /tmp/rtest.txt //去掉全部的r权限 [root@svr5 ~]# ls -ld /tmp/rtest.txt //确认设置结果 --w------- 1 root root 33139 12-11 10:43 /tmp/rtest.txt [root@svr5 ~]# [ -r "/tmp/rtest.txt" ] && echo "可读" || echo "不可读" 可读 //root测试结果仍然可读
切换为普通用户,再执行相同的测试,结果变为“不可读”:
[zengye@svr5 ~]$ [ -r "/tmp/rtest.txt" ] && echo "可读" || echo "不可读" 不可读
普通用户只对本身拥有r权限的文件或目录,-r测试时结果才成立:
[zengye@svr5 ~]$ ls -l .bashrc -rw-r--r-- 1 zengye zengye 124 09-24 16:44 .bashrc [zengye@svr5 ~]$ [ -r ".bashrc" ] && echo "可读" || echo "不可读" 可读
5)-w 判断对象是否可写
此测试一样对root用户无效,不管文件是否设置w权限,root均可写:
[root@svr5 ~]# chmod -w /tmp/rtest.txt //去掉全部的w权限 [root@svr5 ~]# ls -l /tmp/rtest.txt //确认设置结果 ---------- 1 root root 33139 12-11 10:43 /tmp/rtest.txt [root@svr5 ~]# [ -w "/tmp/rtest.txt" ] && echo "可写" || echo "不可写" 可写
切换为普通用户,能够正常使用-w测试:
[zengye@svr5 ~]$ ls -l /tmp/rtest.txt ---------- 1 root root 33139 12-11 10:52 /tmp/rtest.txt [zengye@svr5 ~]$ [ -w "/tmp/rtest.txt" ] && echo "可写" || echo "不可写" 不可写 [zengye@svr5 ~]$ ls -l .bashrc -rw-r--r-- 1 zengye zengye 124 09-24 16:44 .bashrc [zengye@svr5 ~]$ [ -w ".bashrc" ] && echo "可写" || echo "不可写" 可写
6)-x 判断对象是否具备可执行权限
这个取决于文件自己、文件系统级的控制,root或普通用户都适用:
[root@svr5 ~]# chmod 644 /tmp/rtest.txt //重设权限,无x [root@svr5 ~]# ls -l /tmp/rtest.txt //确认设置结果 -rw-r--r-- 1 root root 33139 12-11 10:52 /tmp/rtest.txt [root@svr5 ~]# [ -x "/tmp/rtest.txt" ] && echo "可执行" || echo "不可执行" 不可执行 [root@svr5 ~]# chmod +x /tmp/rtest.txt //添加x权限 [root@svr5 ~]# [ -x "/tmp/rtest.txt" ] && echo "可执行" || echo "不可执行" 可执行
步骤五:多个条件/操做的逻辑组合
1)&&,逻辑与
给定条件必须都成立,整个测试结果才为真。
检查变量X的值是否大于10,且小于30:
[root@svr5 ~]# X=20 //设置X变量的值为20 [root@svr5 ~]# [ $X -gt 10 ] && [ $X -lt 30 ] && echo "YES" YES
多个条件组合时,可使用 [[ .. ]] 界定,好比上述测试能够改成以下:
[root@svr5 ~]# [[ $X -gt 10 && $X -lt 30 ]] && echo "YES" YES
2)||,逻辑或
只要其中一个条件成立,则整个测试结果为真。
检查变量X的值是否小于10或者小于30:
[root@svr5 ~]# [[ $X -lt 10 || $X -lt 30 ]] && echo "YES" YES
只要/tmp/、/var/spool/目录中有一个可写,则条件成立:
[root@svr5 ~]# [ -w "/tmp/" ] || [ -w "/var/spool/" ] && echo "OK" OK
3 案例3:使用if选择结构
3.1 问题
本案例要求编写3个Shell脚本,分别实现如下目标:
检测/media/cdrom目录,若不存在则建立 检测并判断指定的主机是否可ping通 从键盘读取一个论坛积分,判断论坛用户等级,等级分类以下:
大于等于90 神功绝世
大于等于80,小于90 登峰造极
大于等于70,小于80 炉火纯青
大于等于60,小于70 略有小成
大于60 初学乍练
3.2 方案
if单分支的语法组成:
if 条件测试 then 命令序列 fi
if双分支的语法组成:
if 条件测试 then 命令序列1 else 命令序列2 fi
if多分支的语法组成:
if 条件测试1 then 命令序列1 elif 条件测试2 then 命令序列2 else 命令序列n fi
if多分支结构实际上至关于多层if嵌套:
if 条件测试1 ; then 命令序列1 else if 条件测试2 ; then 命令序列2 else .. .. 命令序列n fi fi
3.3 步骤
实现此案例须要按照以下步骤进行。
步骤一:检测/media/cdrom目录,若不存在则建立
1)编写脚本以下:
[root@svr5 ~]# vim chkmountdir.sh #!/bin/bash MOUNT_DIR="/media/cdrom/" if [ ! -d $MOUNT_DIR ] then mkdir -p $MOUNT_DIR fi [root@svr5 ~]# chmod +x chkmountdir.sh //添加可执行权限
2)测试、验证脚本功能
[root@svr5 ~]# ls -ld /media/cdrom //原本没有/media/cdrom目录 ls: /media/cdrom: 没有那个文件或目录 [root@svr5 ~]# ./chkmountdir.sh //执行脚本 [root@svr5 ~]# ls -ld /media/cdrom //再检查已经有了 drwxr-xr-x 2 root root 4096 12-11 15:16 /media/cdrom
有了/media/cdrom文件夹之后,再次执行上述脚本,实际上不作任何有效操做:
[root@svr5 ~]# ./chk_bakdir.sh [root@svr5 ~]#
步骤二:检测并判断指定的主机是否可ping通
1)分析任务需求
使用ping命令检测目标主机时,人工可直接判断反馈结果,而脚本却不方便。可是当ping测试成功时,执行状态$?的值为0;而ping测试失败时,$?的值不为0。所以在Shell脚本中能够利用这一点来判断ping目标主机的成败。
为了节省ping测试时间,能够只发送3个测试包(-c 3)、缩短发送测试包的间隔秒数(-i 0.2)、等待反馈的超时秒数【-W(timeout) 3】。好比,检查可ping通的主机:
[root@svr5 ~]# ping -c 3 -i 0.2 -W 3 192.168.4.5 PING 192.168.4.5 (192.168.4.5) 56(84) bytes of data. 64 bytes from 192.168.4.5: icmp_seq=1 ttl=64 time=0.131 ms 64 bytes from 192.168.4.5: icmp_seq=2 ttl=64 time=0.076 ms 64 bytes from 192.168.4.5: icmp_seq=3 ttl=64 time=0.073 ms --- 192.168.4.5 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 402ms rtt min/avg/max/mdev = 0.073/0.093/0.131/0.027 ms [root@svr5 ~]# echo $? //执行状态表示成功 0
2)脚本编写参考以下:
[root@svr5 ~]# vim pinghost.sh #!/bin/bash ping -c 3 -i 0.2 -W 3 $1 &> /dev/null if [ $? -eq 0 ] ; then echo "Host $1 is up." else echo "Host $1 is down." fi [root@svr5 ~]# chmod +x pinghost.sh
3)测试、验证脚本功能
[root@svr5 ~]# ./pinghost.sh 192.168.4.5 Host 192.168.4.5 is up. [root@svr5 ~]# ./pinghost.sh 192.168.4.50 Host 192.168.4.50 is down.
步骤三:从键盘读取一个论坛积分,判断论坛用户等级
1)脚本编写参考以下:
大于等于90 神功绝世
大于等于80,小于90 登峰造极
大于等于70,小于80 炉火纯青
大于等于60,小于70 略有小成
大于60 初学乍练
[root@svr5 ~]# vim gradediv.sh #!/bin/bash read -p "请输入积分(0-100):" JF if [ $JF –ge 90 ] ; then echo "$JF 分,神功绝世" elif [ $JF –ge 80 ] ; then echo "$JF 分,登峰造极" elif [ $JF –ge 70 ] ; then echo "$JF 分,炉火纯青" elif [ $JF –ge 60 ] ; then echo "$JF 分,略有小成" else echo "$JF 分,初学乍练" fi [root@svr5 ~]# chmod +x gradediv.sh
2)测试、验证脚本
[root@svr5 ~]# ./gradediv.sh 请输入积分(0-100):74 74 分,炉火纯青 [root@svr5 ~]# ./gradediv.sh 请输入分数(0-100):68 68 分,略有小成 [root@svr5 ~]# ./gradediv.sh 请输入分数(0-100):87 87 分,登峰