Linux运维---shell脚本练习串烧1

脚本说明
1.脚本1:解决重装大量的库文件
2.脚本2:选择并切换到想要切换的工作目录

脚本1说明:

某位员工的centos7主机系统出现如下问题:

执行ldconfig命令时报如下错误:库文件是空的,长度为0,需要重装这些库文件。               
ldconfig: File /lib/libstdc++.so.6 is empty, not checked.
ldconfig: File /lib/libstdc++.so.6.0.19 is empty, not checked.
ldconfig: File /lib/libaudit.so.1 is empty, not checked.
ldconfig: File /lib/libaudit.so.1.0.0 is empty, not checked.
ldconfig: File /lib/libauparse.so.0 is empty, not checked.
ldconfig: File /lib/libauparse.so.0.0.0 is empty, not checked.
ldconfig: File /lib/libdw-0.172.so is empty, not checked.
ldconfig: File /lib/liblz4.so.1 is empty, not checked.
ldconfig: File /lib/libelf-0.172.so is empty, not checked.
ldconfig: File /lib/libasm-0.172.so is empty, not checked.
ldconfig: File /lib/liblz4.so.1.7.5 is empty, not checked.
ldconfig: File /lib64/libXfont.so.1 is empty, not checked.
ldconfig: File /lib64/libXfont.so.1.4.1 is empty, not checked.
ldconfig: File /lib64/libical.so.1 is empty, not checked.
ldconfig: File /lib64/libical.so.1.0.1 is empty, not checked.
ldconfig: File /lib64/libicalss.so.1 is empty, not checked.
ldconfig: File /lib64/libicalss.so.1.0.1 is empty, not checked.
ldconfig: File /lib64/libicalvcal.so.1 is empty, not checked.
ldconfig: File /lib64/libicalvcal.so.1.0.1 is empty, not checked.
ldconfig: File /lib64/libminizip.so.1 is empty, not checked.
ldconfig: File /lib64/libminizip.so.1.0.0 is empty, not checked.
ldconfig: File /lib64/libgit2-glib-1.0.so.0 is empty, not checked.
ldconfig: File /lib64/libgit2-glib-1.0.so.0.2600.4 is empty, not checked.
ldconfig: File /lib64/libopenconnect.so.5.4.0 is empty, not checked.
ldconfig: File /lib64/libnghttp2.so.14.16.1 is empty, not checked.
.............省略

如上所示:需要重装这些库文件,不过并不是每行信息显示的都是库文件,有的行是软链接文件,因为链接的库文件为空,所以软链接文件也为空。

脚本1思路
1.首先需要截取出库文件的完整路径和名称,比如(/lib64/libical.so)这样。
2.通过rpm -qf 库文件名能够查出该库文件属于哪个软件包,重装该软件包即可。
3.需要针对软链接文件做判断,如果是链接文件,就不执行重装命令。
4.使用循环去遍历库文件列表,这里使用的是while循环。

脚本1内容

#/bin/bash
LDCONFIG=`ldconfig 2>&1|sort|awk '{print $3}'`        #截取出库文件名称,因为ldconfig命令输出的是错误输出消息,所以这里用2>&1将错误输出重定向到标准输出,管道后的命令才能接受信息。

echo "$LDCONFIG" |           #这里用管道这种方式让while循环处理库文件列表,注意加上双引号
while read line                      #while read line 经典组合
 do
   if [ `ls -l $line | grep -c '^l'` -ne 0 ]         #判断文件是否是链接文件,grep -c 统计匹配串出现的次数,如果是链接文件,grep -c '^l' 就是1,1不等于0成立,执行continue语句,跳出当前循环
     then
         continue
   else
         PACKAGE=`rpm -qf $line`             #如果是库文件,那么查询该库文件属于哪个包
         if [ `echo "$PACKAGE" | wc -l` -eq 1 ]   #判断库文件属于的包是否只有一个,如果只有一个,就重装该包
           then
                echo "prepare reinstall $PACKAGE"
                yes | yum reinstall $PACKAGE        #yes命令如果不跟参数,就会一直输出y,为什么不使用yum -y install? 因为无聊
                [ $? -eq 0 ] && echo "$PACKAGE reinstall succes" || echo "$PACKAGE reinstall failed"  
           else  
                echo 'I don not know need reinstall which PACKAGE'               
         fi
   fi
 done

脚本1小结
该脚本没有针对日志信息,以及安装出错等其他信息的记录,简单的满足重装大量库文件,不能重装的库文件单独解决即可。

脚本2说明

工作中经常频繁的切换到某些目录,刚好看书看到pushd、popd、dirs等命令的介绍,就想写个利用这些命令来切换目录的脚本,该脚本用到的命令说明:

1.pushd命令:shell内置命令,pushd命令带上目录名作为参数的使用可以将该目录添加到目录栈中。如果参数是+n(这里n是一个数字),pushd将旋转栈,从最左边开始栈中的第n个目录将被放到栈顶,同时切换到该目录。..........(内容来自Unix shell范例精解第四版)

2.popd命令:shell内置命令,popd命令从栈顶删除一个目录并切换到那个目录。............(内容来自Unix shell范例精解第四版)

3.dirs命令:带-l选项的内置命令dirs,将以完全路径名的格式显示目录栈中的所有目录。...........(内容来自Unix shell范例精解第四版)

脚本2思路

1.使用select制作目录菜单,选择哪个目录就切换到该目录
2.需要用pushd将目录加入目录栈,用popd命令将目录从目录栈中弹出
3.需要用dirs命令例出目录栈中的目录以及目录的编号

脚本2内容

这是写到/etc/profile文件中的一个函数,刚开始单独写成脚本文件然后执行脚本,发现并没有切换目录,应该是执行脚本时产生了新的进程,所以在当前进程并没有切换目录,后面就没有继续测试脚本了,就将它写成函数放到/etc/profile文件里,内容如下:

function cdir ()       #函数名称cdir
{
DIRS="                  #该变量存放目录列表
/home/kevin.tao/git-server/puppet/modules/nagios/files/client/centos7
/home/kevin.tao/git-server/puppet/modules/nagios/files/server/objects
/home/kevin.tao/git-server/puppet/modules/db_backup
/home/kevin.tao/git-server/puppet/manifests
/home/kevin.tao/Desktop"
set $DIRS             #set 命令可以给位置参数重新赋值,这里就把目录名变成$1 $2 $3 $4 ........
while popd ; do : ; done &>/dev/null    #while循环条件是popd命令,将目录栈清空,如果不清空,每执行一次函数,就会重复添加目录到目录栈中,这样就不对了
until [ -z $1 ]          #until循环用来将目录添加到目录栈中,注意shift命令
do
   pushd $1 &>/dev/null
   shift
done
PUSH=`dirs -l -v|sed '$d'|sed 's/ //g'`    #PUSH变量用来存放目录栈中的目录列表以及目录编号(n)
PS3="Please choose directory"           
select DIR in $PUSH                            #select菜单,选择要切换的目录
do
    NUM=${DIR%%/*}               #选择了哪个目录,这里就会将该目录在栈中的目录编号截取出来
    pushd +$NUM &>/dev/null       #pushd命令加上目录编号就能切换到该目录
    break
done 
}

export -f cdir

脚本2小结

写脚本的时候会遇到很多问题,需要慢慢去修补漏洞。刚开始以为不需要用到popd命令,后面发现目录栈中重复目录太多,只能一个个目录弹出。如果使用cd命令估计就会容易得多,但是没有试过,想多尝试一些不同的方法、不同的技巧,这样更能提升shell编程的能力。

上一篇:Centos7 同时运行PHP5.2和PHP7.1配置


下一篇:CentOS7下使用C/C++连接MariaDB/MySQL