【脚本41】获取ip
提示用户输入网卡的名字,然后我们用脚本输出网卡的ip。 看似简单,但是需要考虑多个方面,比如我们输入的不符合网卡名字的规范,怎么应对。名字符合规范,但是根本就没有这个网卡有怎么应对。
- 代码参考:
#!/bin/bash
while :
do
read -p "请输入网卡名: " e
e1=`echo "$e" | sed 's/[-0-9]//g'`
e2=`echo "$e" | sed 's/[a-zA-Z]//g'`
if [ -z $e ]
then
echo "你没有输入任何东西"
continue
elif [ -z $e1 ]
then
echo "不要输入纯数字在centos中网卡名是以eth开头后面加数字"
continue
elif [ -z $e2 ]
then
echo "不要输入纯字母在centos中网卡名是以eth开头后面加数字"
continue
else
break
fi
done
ip() {
ifconfig | grep -A1 "$1 " |tail -1 | awk '{print $2}' | awk -F ":" '{print $2}'
}
myip=`ip $e`
if [ -z $myip ]
then
echo "抱歉,没有这个网卡。"
else
echo "你的网卡IP地址是$myip"
fi
【脚本42】列出子目录
脚本的功能:
脚本可以带参数也可以不带,参数可以有多个,每个参数必须是一个目录,脚本检查参数个数,若等于0,则列出当前目录本身;否则,显示每个参数包含的子目录。参考代码:
#!/bin/bash
if [ $# == 0 ]
then
ls -ld `pwd`
else
for i in `seq 1 $#`
do
a=$i
echo "ls ${!a}"
ls -l ${!a} |grep '^d'
done
fi
- 标注:
你可能会对${!a}有疑问,这里是一个特殊用法,在shell中,$1为第一个参数,$2为第二个参数,以此类推,那么这里的数字要是一个变量如何表示呢?比如n=3,我想取第三个参数,能否写成 $$n? shell中是不支持的,那怎么办? 就用脚本中的这种方法: a=$n, echo ${!a}
【脚本43】下载文件
创建一个函数,能接受两个参数:
第一个参数为URL,即可下载的文件;第二个参数为目录,即下载后保存的位置;
如果用户给的目录不存在,则提示用户是否创建;如果创建就继续执行,否则,函数返回一个51的错误值给调用脚本;
如果给的目录存在,则下载文件;下载命令执行结束后测试文件下载成功与否;如果成功,则>返回0给调用脚本,否则,返回52给调用脚本;
提示,在函数中返回错误值给调用脚本,使用return
- 参考代码:
#!/bin/bash
if [ ! -d $2 ]
then
echo "please make directory"
exit 51
fi
cd $2
wget $1
n=`echo $?`
if [ $n -eq 0 ];then
exit 0
else
exit 52
fi
【脚本44】猜数字
写一个猜数字脚本,当用户输入的数字和预设数字(随机生成一个小于100的数字)一样时,直接退出,否则让用户一直输入,并且提示用户的数字比预设数字大或者小。
- 参考代码:
#!/bin/bash
m=`echo $RANDOM`
n1=$[$m%100]
while :
do
read -p "Please input a number: " n
if [ $n == $n1 ]
then
break
elif [ $n -gt $n1 ]
then
echo "bigger"
continue
else
echo "smaller"
continue
fi
done
echo "You are right."
【脚本45】抽签脚本
- 写一个脚本执行后,输入名字,产生随机数01-99之间的数字。
- 如果相同的名字重复输入,抓到的数字还是第一次抓取的结果,
- 前面已经抓到的数字,下次不能在出现相同数字。
- 第一个输入名字后,屏幕输出信息,并将名字和数字记录到文件里,程序不能退出
继续等待别的学生输入。
- 参考代码:
while :
do
read -p "Please input a name:" name
if [ -f /work/test/1.log ];then
bb=`cat /work/test/1.log | awk -F: '{print $1}' | grep "$name"`
if [ "$bb" != "$name" ];then #名字不重复情况下
aa=`echo $RANDOM | awk -F "" '{print $2 $3}'`
while :
do
dd=`cat /work/test/1.log | awk -F: '{print $2}' | grep "$aa"`
if [ "$aa" == "$dd" ];then #数字已经存在情况下
echo "数字已存在."
aa=`echo $RANDOM | awk -F "" '{print $2 $3}'`
else
break
fi
done
echo "$name:$aa" | tee -a /work/test/1.log
else
aa=`cat /work/test/1.log | grep "$name" | awk -F: '{print $2}'` #名字重复
echo $aa
echo "重复名字."
fi
else
aa=`echo $RANDOM | awk -F "" '{print $2 $3}'`
echo "$name:$aa" | tee -a /work/test/1.log
fi
done
【脚本46】打印只有一个数字的行
如题,把一个文本文档中只有一个数字的行给打印出来。
- 参考代码:
#!/bin/bash
f=/etc/passwd
line=`wc -l $f|awk '{print $1}'`
for l in `seq 1 $line`; do
n=`sed -n "$l"p $f|grep -o '[0-9]'|wc -l`;
if [ $n -eq 1 ]; then
sed -n "$l"p $f
fi
done
【脚本47】日志归档
类似于日志切割,系统有个logrotate程序,可以完成归档。但现在我们要自己写一个shell脚本实现归档。
举例:
假如服务的输出日志是1.log,我要求每天归档一个,1.log第二天就变成1.log.1,第三天1.log.2, 第四天 1.log.3 一直到1.log.5参考答案:
#!/bin/bash
function e_df()
{
[ -f $1 ] && rm -f $1
}
for i in `seq 5 -1 2`
do
i2=$[$i-1]
e_df /data/1.log.$i
if [ -f /data/1.log.$i2 ]
then
mv /data/1.log.$i2 /data/1.log.$i
fi
done
e_df /data/1.log.1
mv /data/1.log /data/1.log.1
【脚本48】找出活动ip
写一个shell脚本,把192.168.0.0/24网段在线的ip列出来。
思路:
for循环, 0.1 — 0.254 依次去ping,能通说明在线。参考代码:
#!/bin/bash
ips="192.168.1."
for i in `seq 1 254`
do
ping -c 2 $ips$i >/dev/null 2>/dev/null
if [ $? == 0 ]
then
echo "echo $ips$i is online"
else
echo "echo $ips$i is not online"
fi
done
【脚本49】检查错误
写一个shell脚本,检查指定的shell脚本是否有语法错误,若有错误,首先显示错误信息,然后提示用户输入q或者Q退出脚本,输入其他内容则直接用vim打开该shell脚本。
提醒:
检查shell脚本有没有语法错误的命令是 sh -n xxx.sh参考代码:
#!/bin/bash
sh -n $1 2>/tmp/err
if [ $? -eq "0" ]
then
echo "The script is OK."
else
cat /tmp/err
read -p "Please inpupt Q/q to exit, or others to edit it by vim. " n
if [ -z $n ]
then
vim $1
exit
fi
if [ $n == "q" -o $n == "Q" ]
then
exit
else
vim $1
exit
fi
fi
【脚本50】格式化输出
输入一串随机数字,然后按千分位输出。
比如输入数字串为“123456789”,输出为123,456,789
- 代码参考:
#!/bin/bash
read -p "输入一串数字:" num
v=`echo $num|sed 's/[0-9]//g'`
if [ -n "$v" ]
then
echo "请输入纯数字."
exit
fi
length=${#num}
len=0
sum=''
for i in $(seq 1 $length)
do
len=$[$len+1]
if [[ $len == 3 ]]
then
sum=','${num:$[0-$i]:1}$sum
len=0
else
sum=${num:$[0-$i]:1}$sum
fi
done
if [[ -n $(echo $sum | grep '^,' ) ]]
then
echo ${sum:1}
else
echo $sum
fi
上面这个实现比较复杂,下面再来一个sed的:
#!/bin/bash
read -p "输入一串数字:" num
v=`echo $num|sed 's/[0-9]//g'`
if [ -n "$v" ]
then
echo "请输入纯数字."
exit
fi
echo $num|sed -r '{:number;s/([0-9]+)([0-9]{3})/\1,\2/;t number}'
【脚本51】
- 编写一个名为iffile程序,它执行时判断/bin目录下date文件是否存在?
- 参考代码:
#!/bin/bash
if [ -f /bin/date ]
then
echo "/bin/date file exist."
else
echo "/bin/date not exist."
fi
- 编写一个名为greet的问候程序,它执行时能根据系统当前的时间向用户输出问候信息。设从半夜到中午为早晨,中午到下午六点为下午,下午六点到半夜为晚上。
- 参考代码:
#!/bin/bash
h=`date +%H`
if [ $h -ge 0 ] && [ $h -lt 12 ]
then
echo "Good morning."
elif [ $h -ge 12 ] && [ $h -lt 18 ]
then
echo "Good afternoon."
else
echo "Good evening."
fi
【脚本52】判断用户登录
- 编写一个名为ifuser的程序,它执行时带用户名作为命令行参数,判断该用户是否已经在系统中登录,并给出相关信息。
- 参考代码:
#!/bin/bash
read -p "Please input the username: " user
if who | grep -qw $user
then
echo $user is online.
else
echo $user not online.
fi
- 编写一个名为menu的程序,实现简单的弹出式菜单功能,用户能根据显示的菜单项从键盘选择执行对应的命令。
- 参考代码:
#!/bin/bash
function message()
{
echo "0\. w"
echo "1\. ls"
echo "2.quit"
read -p "Please input parameter: " Par
}
message
while [ $Par -ne '2' ] ; do
case $Par in
0)
w
;;
1)
ls
;;
2)
exit
;;
*)
echo "Unkown command"
;;
esac
message
done
【脚本53】更改后缀名
- 编写一个名为chname的程序,将当前目录下所有的.txt文件更名为.doc文件。
- 参考代码:
#!/bin/bash
find . -type f -name "*.txt" > /tmp/txt.list
for f in `cat /tmp/txt.list`
do
n=`echo $f|sed -r 's/(.*)\.txt/\1/'`
echo "mv $f $n.doc"
done
- 编写一个名为chuser的程序,执行中每隔5分钟检查指定的用户是否登录系统,用户名从命令行输入;如果指定的用户已经登录,则显示相关信息。
- 参考代码:
#!/bin/bash
read -p "Please input the username: " user
while :
do
if who | grep -qw $user
then
echo $user login.
else
echo $user not login.
fi
sleep 300
done
【脚本54】判断pid是否一致
先普及一小段知识,我们用ps aux可以查看到进程的PID,而每个PID都会在/proc内产生。如果查看到的pid而proc内是没有的,则是进程被人修改了,这就代表你的系统很有可能已经被*过了。
请大家用上面知识编写一个shell,定期检查下自己的系统是否被人***过。
- 参考代码:
#!/bin/bash
ps aux|awk '/[0-9]/ {print $2}'|while read pid
do
result=`find /proc/ -maxdepth 1 -type d -name "$pid"`
if [ -z $result ]; then
echo "$pid abnormal!"
fi
done
【脚本55】一列变三行
比如1.txt内容:
1
2
3
4
5
6
7
处理后应该是:
1 2 3
4 5 6
7
可使用sed命令完成:
sed 'N;N;s/\n/ /g' 1.txt
【脚本56】shell的getops
写一个getinterface.sh 脚本可以接受选项[i,I],完成下面任务:
使用一下形式:getinterface.sh [-i interface | -I ip]
当用户使用-i选项时,显示指定网卡的IP地址;当用户使用-I选项时,显示其指定ip所属的网卡。
- 例:
sh getinterface.sh -i eth0
sh getinterface.sh -I 192.168.0.1
当用户使用除[-i | -I]选项时,显示[-i interface | -I ip]此信息。
当用户指定信息不符合时,显示错误。(比如指定的eth0没有,而是eth1时)
- 参考代码:
#!/bin/bash
ip add |awk -F ":" '$1 ~ /^[1-9]/ {print $2}'|sed 's/ //g' > /tmp/eths.txt
[ -f /tmp/eth_ip.log ] && rm -f /tmp/eth_ip.log
for eth in `cat /tmp/eths.txt`
do
ip=`ip add |grep -A2 ": $eth" |grep inet |awk '{print $2}' |cut -d '/' -f 1`
echo "$eth:$ip" >> /tmp/eth_ip.log
done
useage()
{
echo "Please useage: $0 -i 网卡名字 or $0 -I ip地址"
}
wrong_eth()
{
if ! awk -F ':' '{print $1}' /tmp/eth_ip.log | grep -qw "^$1$"
then
echo "请指定正确的网卡名字"
exit
fi
}
wrong_ip()
{
if ! awk -F ':' '{print $2}' /tmp/eth_ip.log | grep -qw "^$1$"
then
echo "请指定正确的ip地址"
exit
fi
}
if [ $# -ne 2 ]
then
useage
exit
fi
case $1 in
-i)
wrong_eth $2
grep -w $2 /tmp/eth_ip.log |awk -F ':' '{print $2}'
;;
-I)
wrong_ip $2
grep -w $2 /tmp/eth_ip.log |awk -F ':' '{print $1}'
;;
*)
useage
exit
esac
【脚本57】3位随机数字
写一个脚本产生随机3位的数字,并且可以根据用户的输入参数来判断输出几组。 比如,脚本名字为 number3.sh。
- 执行方法:
bash number3.sh
直接产生一组3位数字。
bash number3.sh 10
插上10组3位数字。
思路:
可以使用echo $RANDOM获取一个随机数字,然后再除以10,取余获取0-9随机数字,三次运算获得一组。参考代码:
#!/bin/bash
get_a_num() {
n=$[$RANDOM%10]
echo $n
}
get_numbers() {
for i in 1 2 3; do
a[$i]=`get_a_num`
done
echo ${a[@]}
}
if [ -n "$1" ]; then
m=`echo $1|sed 's/[0-9]//g'`
if [ -n "$m" ]; then
echo "Useage bash $0 n, n is a number, example: bash $0 5"
exit
else
for i in `seq 1 $1`
do
get_numbers
done
fi
else
get_numbers
fi
【脚本58】检查服务
先判断是否安装http和mysql,没有安装进行安装,安装了检查是否启动服务,若没有启动则需要启动服务。
说明:
操作系统为centos6,httpd和mysql全部为rpm包安装。参考代码:
#!/bin/bash
if_install()
{
n=`rpm -qa|grep -cw "$1"`
if [ $n -eq 0 ]
then
echo "$1 not install."
yum install -y $1
else
echo "$1 installed."
fi
}
if_install httpd
if_install mysql-server
chk_ser()
{
p_n=`ps -C "$1" --no-heading |wc -l`
if [ $p_n -eq 0 ]
then
echo "$1 not start."
/etc/init.d/$1 start
else
echo "$1 started."
fi
}
chk_httpd
chk_mysqld