6.3 bash编程 字符测试
给定一个用户,判断其UID和GID是否一样 "^$USERNAME\>"(行首第一个单词)
如果一样,就显示此用户为"good guy";否则,就显示此用户为"bad guy"
#!/bin/bash
#
USERNAME =user1
if !grep "^$USERNAME\>" /etc/passwd &> /dev/null;then 用户不存在
echo "No such user: $USERNAME."
exit 1
fi
USERID = `id -u $USERNAME`
GROUPID =`id -g $USERNAME`
if[ $USERID -eq $GROUPID ];then
echo "good guy"
else
echo "bad guy"
fi
exit: 退出脚本
exit #(#代表数字)
bash中常用的条件测试三种
-gt
-le
-ne
-ge
-lt
-eq 非0值都是假
--------------------只有上面才能用[],其他表达式中不能出现[]
INT1 = 63
INT2 = 77
[ $INT1 -eq $INT2 ]
[[ $INT1 -eq $INT2 ]]
TEST $INT1 -eq $INT2
if [ `grep "^$USENAME\>" /etc/passwd | cut -d: -f3` -eq 0 ];then 对
if [ `grep "^$USENAME\>" /etc/passwd ` -eq 0 ];then 错(前面是一行)
测试方法
[ expression ] bash的命令
` expression ` bash关键字
test expression
文件测试:
-e FILE:测试一个文件是否存在
-f FILE:测试文件是否为普通文件
-d FILE: 测试指定路径是否为目录的
-r FILE: 测试当前用户对指定文件是否有读取权限
-w
-x FILE
[ -e /etc/initttab ]
[ -x /etc/rc.d/rc.sysinit ]
练习:写一个脚本
给定一个文件,比如/etc/inittab
判断这个文件中是否有空白行
如果有,则显示其空白行数,否则,显示没有空白行
#!/bin/bash
FILE = /etc/inittab
if [! -e $FILE ];then
echo "No $FILE."
exit 8
fi
if grep "^$" $FILE &> /dev/null;then
echo "Total blank lines: `grep "^$" $FILE | wc -l`."
else
echo "No blank line."
fi
圆整,丢弃小数点后的内容
expr命令一般用于整数值
#expr argument operator argument
练习:编写一个脚本
给定一个用户,获取其密码警告期限:
而后判断用户最近一次修改密码时间距今天是否已经小于警告期限
提示:算术运算的方法$[$A-$B]:表示变量A的值减去变量B的值的结果
如果小于,则显示"Warning":否则,就显示"OK"
#!/bin/bash
#
W=`grep "student" /etc/shadow | cut -d: -f6`
S=`date +%s`
T=`expr $S/86400`
L=`grep "^student" /etc/shadow | cut -d: -f5`
N=`grep "^student" /etc/shadow | cut -d: -f3`
SY=$[$L-$[$T-$N]]
if [ $SY -lt $W ];then
echo 'Worning'
else
echo 'OK'
fi
练习:写一个脚本
判读命令历史中历史命令的总条目是否大于1000;如果大于,则显示
"Some command will gone.";否则显示"ok"
history 当前显示缓冲区中的条数(会大于1000)
$HISTSIZE 都只显示1000
$HISTFILESIZE 都只显示1000
history | tail -l | cut -d' ' -f1 由于前面有一个空格,取不出条数,当取第二个字段
history | tail -l | cut -d' ' -f2
#!/bin/bash
#
COUNT = history | tail -l | cut -d' ' -f2
if $COUNT -gt 1000 ;then
echo "Some command will gone."
else
echo "ok"
fi
多分支的if语句
if 判断条件1;then
statement1
...
elif 判断条件2;then
statement2
...
elif 判断条件3;then
statement3
...
else 判断条件4;then
statement4
...
fi
#!/bin/bash
#
FILE =/etc/inittab
if [ -e $FILE ];then
echo "OK"
else
echo "No such file"
fi
测试脚本是否有语法错误
bash -n filetest.sh
bash -x 脚本:单步执行
给定一个文件,如果是一个普通文件,就显示之
如果是一个目录,亦显示之
否则,此为无法识别之文件
filetest2.sh
#!/bin/bash
#
FILE = /etc/rc.d/rc.sysinit
if [ ! -e $FILE ];then
echo "NO such file"
exit 6
fi
if [ -f $FILE ];then
echo "Common file"
elif [ -d $FILE ];then
echo "Directory"
else
echo "Unkown."
fi
定义脚本退出状态码
如果脚本没有明确定义退出状态码,那么,最后执行的一条命令
的退出码即为脚本的退出状态码
bash变量的类型:
本地变量(局部变量) 当前shell进程
环境变量 当前shell进程及其子进程
位置变量:$1 $2 ...
shift(踢掉一个位置值)默认踢1个
shift [n]踢掉n个
特殊变量 $?
$#:参数的个数
$*:参数列表
$@:参数列表
./filetest.sh /etc/fstab /etc/inittab
$1:/etc/fstab
$2:/etc/inittab
练习:写一个脚本
能接受一个参数(文件路径)
判定:此参数如果是一个存在的文件,就显示OK ,否则显示No such file
#!/bin/bash
#
echo $#
echo $*
echo $@
if[ $# -lt 1 ];then
echo "Usage: ./filetest3.sh ARG1 [ARG2 ...]"
if [ -e $1 ];then
echo "ok"
else
echo "No such file"
fi
练习:写一个脚本
给脚本传递两个参数(整数)
显示此两个参数之和,之乘积
#!/bin/bash
#
if [ $# -lt 2 ];then
echo "Usage: cac1.sh ARG1 ARG2"
exit
fi
echo "The sum is : $[$1 + $2]."
echo "The prod is : $[$1 * $2]."
sed -n 静默
-i 直接修改原文件
-e SCRIPT -e SCRIPT:可以同时执行多个脚本
-f /PATH/TO/SED_SCRIPT
sed -f /path/to/scripts file
这个文件是脚本一行一个脚本运用在file上
-r :表示使用扩展正则表达式
删除行首的空格
history | sed 's#^[[:space:]]*##g'
history | sed 's#^[[:space:]]+##g'
g:全局替换
i:忽略字符大小写
s///:s###,s@@@
sed 's#l..e#&r#g' sed.txt
sed 's#\(l..e\)#\1r#g' sed.txt 后项引用
like - Like
love - Love
sed 's#l\(..e\)#L\1#g' sed.txt
&:引用模式匹配到的整个串
sed练习:
1 删除/etc/grub.conf文件中行首的空白符
sed -r 's@^[[:space:]]+@@g' /etc/grub.conf
2 替换/etc/inittab文件中"id:3:initdefault:"一行
中的数字为5
sed 's@\(id:\)[0-9]\(:initdefault:\)@\15\2@g' /etc/inittab
3 删除/etc/inittab文件中的空白行
sed '/^$/d' /etc/inittab
4 删除/etc/inittab文件中开头的#号
sed 's@^#@@g' /etc/inittab
5 删除/etc/inittab文件中开头的#号及后面的空白字符,但要求
#号后面必须有空白字符
sed -r 's@^#[[:space:]]+@@g' /etc/inittab
6 删除某文件中以空白字符后面跟#类的行中的开头的
空白字符及#
sed -r 's@^[[:space:]]+@@g' /inittab
7 取出一个文件路径的目录名称
echo "/etc/rc.d/" | sed -r 's@^(/.*/)[^/]+/?@\1@g' 取etc
基名:
echo "/etc/rc.d/" | sed -r 's@^/.*/([^/]+)/?@\1@g' 取rc.d
#abc
# hello world
# hi world
练习:
传递一个用户名参数给脚本,判断此用户名跟其基本组的
组名是否一致,并将结果显示出来
[ ]条件是
vi testUser.sh
#!/bin/bash
#
if !id $1 &>/dev/null;then
echo "No such user."
exit 8
fi
#if [ `id -n -u $1` == `id -n -g $1`];then
if [ $1 == `id -n -g $1`];then 用户名本来就是一个字符串
echo "yiyang"
else
echo "buyiyang"
fi
字符测试:
== [ $A = $B ]
!= [ $A != $B ]
>
<
-n string:测试指定字符串是否为空,空真
-z string:测试指定字符串是否不空,不空真
练习:写一个脚本
传递一个参数(单字符就行)给脚本,如果参数为q,就退出脚本;
否则,就显示用户的参数
练习:写一个脚本
传递一个参数(单字符就行)给脚本,如果参数为q、Q、Quit,就退出脚本;
否则,就显示用户的参数
#!/bin/bash
#
if [ $1 = 'q' ];then
echo "Quiting..."
exit 1
elif [ $1 = 'Q' ];then
echo "Quiting..."
exit 2
elif [ $1 = 'quit' ];then
echo "Quiting..."
exit 3
elif [ $1 = 'Quit' ];then
echo "Quiting..."
exit 4
else
echo $1
fi
练习:
传递三个参数给脚本,第一个为整数;第二个为算术运算符,
第三个为整数,将计算结果显示出来,要求保留两位精度,
形如:
./calc.sh 5 /2
echo "scale=2;111/22;" | bc 答案5.02
bc <<< "scale=2;111/22;"
练习:
传递3个参数给脚本,参数均为用户名,将此些用户的账号信息取
出来后放置于/tmp/testusers.txt文件中,并要求每一行行首
有行号
添加行号
echo "1 $LINE" >> /tmp/testusers
echo "2 $LINE" >> /tmp/testusers
练习:
判断当前主机的CPU生产商,其信息在/proc/cpuinfo文件中vendor id
一行中,如果其生产商为AuthenticAMD,就显示其为AMD公司;如果生
产商为GenuineIntel,就显示其为Intel公司:否则,就说其为非主流
公司:
写一个脚本:
给脚本传递三个参数,判断其中的最大数和最小数,并显示出来
MAX=0
-eq -lt
写一个脚本:
1 设定变量FILE的值为/etc/passwd
2 依次向/etc/passwd中的每个用户问好,并显示对方的shell,形如:
Hello,root,your shell:/bin/bash
3 统计一共有多少用户
LINES = `wc -l /etc/passwd | cut -d' ' -f1`
for I in `seq 1 $LINES`;do
echo "hello, `head -n $I /etc/passwd | tail -1 | cut -d: -f1`"
只向默认shell为bash的用户问声好
写一个脚本:
1 添加10个用户user1到user10,但要求只有用户不存在的情况下才能
添加,密码同用户名
扩展:
接收一个参数
add:添加用户user1..user10
del:删除用户user1..user10
其他,退出
adminusers --add user1,user2,user3,hello,hi
vim adminuser2.sh
#/bin/bash
#
#echo $1
#echo $1 | tr -d','删除所有的逗号
#echo $1 |sed 's/,/ /g'
for I in `echo $1 |sed 's/,/ /g'`;do
if id $I &> /dev/null;then
echo "$I exist."
else
useradd $I
echo $I | passwd --stdin $I &> /dev/null
echo "add $I finished."
fi
done
vim adminuser3.sh
#/bin/bash
#
if [ $1 == '--add' ];then
for I in `echo $2 |sed 's/,/ /g'`;do
if id $I &> /dev/null;then
echo "$I exist."
else
useradd $I
echo $I | passwd --stdin $I &> /dev/null
echo "add $I finished."
fi
done
elif [ $1 == '--del' ];then
for I in `echo $2 |sed 's/,/ /g'`;do
if id $I &>/dev/null;then
userdel -r $I
echo "Delete $I finished."
else
echo "$I not exist."
fi
done
elif [ $1 == '--help' ]
echo "Usage:adminuser2.sh --add USER1,USER2,... | --del USER1,USER2,... --help"
else
echo "Unkown ARG"
exit 8
fi
在剩下的三个月里,你愿意与学习结为伴侣,无论贫穷还是富贵,
无论电脑还是手机,无论多困或者多累,无论想吃还是想睡,
都要把学习放在第一位,以不落后为目标,同甘共苦同舟共济
永不言弃,爱惜她,尊重她,理解她,保护她,你愿意这样做吗
vim adduser.sh
#!/bin/bash
#
for I in {1..10};do
if id user$I &>/dev/null;then
echo "user$I exist."
else
useradd user$I
echo user$I | passwd --stdin user$I &>/dev/null
echo "ADD user user$I finished"
fi
done
vim deluser.sh
#!/bin/bash
#
for I in {1..10};do
if id user$I &>/dev/null;then
userdel -r user$I
echo "Delete user$I finished."
else
echo "user$I not exist."
fi
done
vi adminnusers.sh
#/bin/bash
#
if [ $# -lt 1 ];then
echo "Usage:adminnusers ARG"
exit 7
fi
if [ $1 == '--add' ];then
for I in {1..10};do
if id user$I &> /dev/null
echo "user$I exist."
else
useradd user$I
echo user$I | passwd --stdin user$I &>/dev/null
echo "ADD user user$I finished"
fi
done
elif [ $1 == '--del' ];then
for I in {1..10};do
if id user$I &>/dev/null;then
userdel -r user$I
echo "Delete user$I finished."
else
echo "user$I not exist."
fi
done
else
echo "Unkown ARG"
exit 8
fi
循环:进入条件,退出条件
for
while
until
for 变量 in 列表;do
循环体
done
for i in 1 2 3 4 5;do
加法运算
done
遍历完成之后,退出:
如何生成列表:
{1..100}
seq [起始数 [步进长度]] 结束数
`ls /etc`也能访问每一个文件的列表
默认变量是字符串
declare -i SUM=0
integer
-x (环境变量)
1,...100
#/bin/bash
#
#let SUM = 0 此时变量是数字let
declare -i SUM=0
for I in {1..100};do
let SUM =$[$SUM+$I]
done
echo "The sum is $SUM."
写一个脚本
计算100以内所有能被3整除的整数的和
取模,取余%
写一个脚本:
计算100以内所有奇数和以及所有偶数的和:分别显示之:
写一个脚本,分别显示当前系统上所有默认shell为bash的用户和默认
shell为/bin/nologin的用户,并统计各类shell下的用户总数,显示
结果形如:
BASH,3users,they are:
root,redhat,gentoo
NOLOGIN,2users,they are:
bin,ftp