1、
单引号 表示强引用,不可修改
双引号 表示弱引用,可修改
2、
引用变量 $ 变量名
本地变量:整个bash进程
局部变量:当前代码段
环境变量:当前shell和其他shell
3、
$#传递到脚本的参数个数
$*传递到脚本的文件个数,可超过9个
$$脚本运行时当前进程的ID号
$!脚本运行时最后一个进程的ID号
$@使用时加引号,并在引号中返回参数个数
$-上一个命令的最后一个参数
$?最后命令的退出状态,0表示无错误,其他数值表示有错误
4、
>覆盖重定向 >>追加重定向
2>错误覆盖重定向 2>>错误追加重定向
&>全部重定向 /dev/null 打入黑洞
5、
-eq 等于 -ne 不等于
-gt 大于 -lt 小于
-ge大于等于 -le小于等于
6、算数运算
C=$[$A+\$B] C=\$((\$A+\$B)) C=expr $A+$B
date +%s 今天的秒数
seq 起始数 跨度数 结束数
7、
if语句格式:(-a逻辑与 -o逻辑或)
if 条件 ; then
语句
elif 条件 ;then
语句
else
语句
fi
8、
for循环语句格式:
for 变量 in 列表 ; do
语句
done
10、
使用while无限循环
格式一:
while 条件 ; do
语句
[break]
done
格式二:
while true do
语句
done
格式三:
while : do
语句
done
格式四:
while [1] do
语句
done
格式五:
while [0] do
语句
done
Shell 习题
注意;由于网页不能识别$,所以在实验Shell答案的时候,凡是$前面的\都去掉,一定记得修改
1、
添加5个用户,user1,,,,user5
每个用户的密码同用户名,要求:添加密码完成后不显示passwd执行结果。
显示添加成功信息
#/bin/bash
for i in seq 5
;do
useradd user$i
echo user$i | passwd –stdin user$i && echo “add user$i sucdessfully” //stdin输入
done
2、
使用一个变量保存一个用户名
删除此变量中的用户,且一并删除其家目录
显示“用户删除成功”信息。
#/bin/bash
id $1 &> /dev/null || echo “user:$1 do not exits” || exit 2 //为真,则不执行
id $1 &> /dev/null && userdel -rf $1 &> /dev/null && echo “del user:$1 success”//为假,不执行
3、
如果用户user6不存在则添加用户user6
#!/bin/bash
#
id $1 &>/dev/null
A=$?
[ $A -eq 0 ] && echo “$1 exists.” && exit 0
useradd $1
echo “\$1” | passwd –stdin \$1 \$>/dev/null
echo “add \$1 success.”
#
或者另一种形式:
#
if id $1 &>/dev/null ; then
echo “$1 exists.”
exit 0
else
useradd $1
echo “$1” | passwd –stdin $1 $>/dev/null
echo “add $1 success.”
fi
4、
如果用户不存d在,添加用户并显示添加成功,否则显示其已存在
#!/bin/bash
#
[ ! $# -eq 1 ] && echo “args error” && exit 5
id $1 &> /dev/null && echo “user: $1 exits” && exit 2
id $1 &> /dev/null || useradd $1
id $1 &> /dev/null && echo “user: $1” && echo $1 | passwd –stdin $1 &> /dev/null && echo “change user: $1 password success!”
5、
如果/etc/inittab文件的行数大于50,就显示大的文件;否则显示小文件
#!/bin/bash
COUNT=wc -l /etc/inittab | cut -d' ' -f1
[ $COUNT -gt 50 ] && echo “it is big file”
[ $COUNT -lt 50 ] && echo “it is small file”
或者另一种形式:
#!/bin/bash
#
COUNT=wc -l /etc/inittab | cut -d' ' -f1
if [ $COUNT -gt 20 ] ;then
echo “it is big file”
else
echo “it is smqll file”
fi
6、
添加3个用户user1.user3,并且设置密码和用户名相同,如果用户已经存在,显示:已存在
添加完成之后计算系统一共有多少个可以访问的用户。
#/bin/bash
for i in seq 3
;do
! id user$i &>/dev/null && useradd user$i
echo user$i | passwd –stdin user$i && echo “add user$i sucdessfully” //stdin输入
cat /etc/passwd | wc -l | sort -u
done
7、
如果其UID=0,就显示其为管理员,否则显示其为普通用户
#/bin/bash
count=cat /etc/passwd | wc -l
echo $count
for i in seq \$count
; do
d=head -$i /etc/passwd | tail -1 | cut -d ':' -f 3
if [ $d -eq 0 ] ; then
echo “admin”
else
echo “normal”
fi
done
或者另一种格式:
awk -F ‘:’ ‘{if($3 == 0){print “admin”}else{print “normal”} }’ /etc/passwd
8、
判断命令历史记录中历史命令的总条目大于500,如果大于,则显示“Some command is done.”,否则显示:“OR”。
#/bin/bash
COUNT=history | wc -l
if [ $COUNT -gt 500 ] ;then
echo “too many commands”
else
echo “OR”
fi
9、
给定三个整数,判断其中的最大值和最小数。并显示出来
#!/bin/bash
#
if [ ! $# -eq 3 ] ;then
echo “args error”
exit 5
fi
BIG=$1
SMALL=$2
if [ $1 -lt $2 ] ;then
BIG=$2
SMALL=$1
fi
if [ $BIG -lt $3 ] ;then
BIG=$3
fi
if [ \$SMALL -gt \$3 ] ;then
SMALL=\$3
fi
echo “big:\$BIG; small:\$SMALL”
10、
给定一个用户,获取其密码警告期限,然后判断用户密码使用期限是否已经小于警告期限,如果小于,则是显示“WARN” ,否则显示密码还有多少天到期。
#!/bin/bash
#
if [ ! $# -eq 1 ] ;then
echo “agrs error”
exit 3
fi
U_DAY=grep $1 /etc/shadow | cut -d: -f3
M_DAY=grep $1 /etc/shadow | cut -d: -f5
W_DAY=grep $1 /etc/shadow | cut -d: -f6
NOW=$[date +%s
/86400]
USED_DAY=$[$NOW-$U_DAY]
LAST_DAY=$[$M_DAY-$USED_DAY]
if [ $LAST_DAY -le $W_DAY ] ;then
echo “warn”
else
echo “left day: $LAST_DAY”
fi
11、
指定一个用户名,判断此用户的用户名和它的基本组 组名是否相同.
#/bin/bash
[ $# -eq 0 ] && echo “pls input username.” && exit 2 //&&第一个为假,不执行;为真一次执行
id $1 &> /dev/null || echo “$1 not exists” && exit 2
if [ $1 == id -n -g $1
];then //-n -g 只显示用户名
echo “equals”
else
echo “not equals”
fi
12、
判断当前主机的CPU生产商,(其信息保存在/proc/cpuinfo文件中)
如果是:AuthemticAMD ,就显示其为AMD公司
GenuineIntel ,就显示其为 Intel公司
否则,就显示其为非主流公司。
#/bin/bash
CPU=head -2 /proc/cpuinfo | tail -1 | cut -d: -f2
if [ $CPU == ‘GenuineIntel’ ] ;then
echo “Intel”
else
echo “AMD”
fi
13、
给定三个用户名,将此些用户的帐号信息提取出来,然后放入/tmp/test.txt文件中,并在行首给定行号。
#!/bin/bash
#
lineno=1
for I
do
echo $lineno grep $I /etc/passwd | cut -d: -f1
>> /tmp/tempusers
lineno=$(( lineno + 1 ))
done
直接for I就行了,后面的in ….都不要,就表示依次取传入参数的值
14、
依次向/etc/passwd中的每个用户问好:hello 用户名,并显示用户的shell:
Hello ,root ,your shell :/bin/bash。
#!/bin/bash
#
COUNT=cat /etc/passwd | wc -l
for I in seq $COUNT
;do
head -$I /etc/passwd| tail -1 | awk -F’:’ ‘{print “hi,”,$1,” your shell is:”,$7}’
done
15、
只向默认shell为bash的用户问好。
#/bin/bash
N=1
C=cat /etc/passwd | wc -l
for I in seq $C
;do
U=head -$I /etc/passwd | tail -1 | cut -d: -f1
//每一行的用户
B=head -$I /etc/passwd | tail -1 | cut -d: -f7
//每一行的登录shell
if [ $B == ‘/bin/bash’ ];then
echo “hello \$U \$N” >> /tmp/text1 //s输出
N=\$[\$N+1]
fi
done
16、
计算100以内所有能被3整除的整数的和
#!/bin/bash
#
SUM=0
I=1
while true
do
if [ $I -gt 100 ] ;then
break
fi
if [ $[$I%3] -eq 0 ] ;then
SUM=$[$SUM+$I]
fi
I=$[$I+1]
done
echo “sum: $SUM”
17、使用echo输出10个随机数,并且一行显示。提示:$RANDOM
#/bin/bash
for i in seq 1 10
;do
echo -n -e “\t$RANDOM” //-n:一行显示 -e:支持正则表达式
done
echo -e
若字符串中出现以下字符,则特别加以处理,而不会将它当成一般文字输出:
\a 发出警告声;
\b 删除前一个字符;
\c 最后不加上换行符号;
\f 换行但光标仍旧停留在原来的位置;
\n 换行且光标移至行首;
\r 光标移至行首,但不换行;
\t 插入tab;
\v 与\f相同;
\ 插入\字符;
\nnn 插入nnn(八进制)所代表的ASCII字符;
练习:把所有可以登陆的用户信息输出到文件中
#!/bin/bash
#
N=1
C=wc -l /etc/passwd | awk '{print $1}'
for I in seq 1 $C
;do
U=head -$I /etc/passwd | tail -1 | cut -d: -f1
//用户名
B=head -$I /etc/passwd | tail -1 | cut -d: -f7
//登录shell
if [ $B == ‘/bin/bash’ ];then
echo -e “\$N \t \$U” >> /tmp/text
N=\$[\$N+1]//计算
fi
done
18、传给脚本一个参数:目录,输出该目录中文件最大的文件名和文件大小:
比如:1.txt 100KB
ls -l | awk ‘{print $5,$9}’ | sort -nr
#!/bin/bash
#
if [ ! -d $1 ] ;then//不是目录
echo “args error”
fi
C=du -a $1 | wc -l
du 查看文件大小
for I in seq $C
;do
FILE_NAME=du -a $1 | sort -nr | head -$I | tail -1 | cut -f2
//文件名称
FILE_SIZE=du -a $1 | sort -nr | head -$I | tail -1 | cut -f1
//文件大小
if [ -f $FILE_NAME ] ;then
echo “\$FILE_NAME , \${FILE_SIZE/1024}kb”
break
fi
done
19、传给脚本一个参数:查看该目录下是否有大小为0的文件,如果有则删除。同时显示删除信息。
#/bin/bash
if ! [ -d $1 ];then//不是目录报错
echo “Args is error.”
exit 3
fi
C=du -a $1 | wc -l
for i in seq $C
;do
S=du -a /etc/ | sort -nr |head -2 | tail -1 |awk '{print $1}'
F=du -a /etc/ | sort -nr |head -2 | tail -1 |awk '{print $2}'
#[ -f $F ] && echo -e “The max File is $F \t $S” && break
if[ -f $F ];then//是文件
if [ $S -eq 0 ];then //文件大小是为0
rm -rf $F
echo “$F is deleted.”
fi
fi
done
#
目录下是否有文件,如果有,
#!/bin/bash
#
if ! [ -d $1 ];then
echo “Args is error.”
exit 3
fi
C=du -a $1 | wc -l
for I in seq $C
;do
S=du -a $1 | sort -nr | head -$I | tail -1 | awk '{print $1}'
//文件的大小
F=du -a $1 | sort -nr | head -$I | tail -1 | awk '{print $2}'
//文件
[ -f $F ] && echo -e “The max File is $F \t $S” && break
done
20、查询当前192.168.1.x网段内,哪些IP被使用了,输出这些IP到一个文件中。
#!/bin/bash
#
N=1
for I in {2..254};do
R=ping -c1 192.168.1.$I | grep received | cut -d, -f2 | cut -d' ' -f2
//输出接受到的包个数
if [ $R -eq 1 ];then
echo -e “\$N \t 192.168.1.\$I” >> /tmp/ips
N=\$[\$N+1]
fi
done
21、请根据一个关键字,杀掉系统进程中包含此关键字的进程。
kill -9
for i in ps aux | grep nginx | awk '{print $2}'
; do kill -9 $i done