linux脚本进阶例题解析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux脚本进阶例题解析相关的知识,希望对你有一定的参考价值。

例题一:编写脚本/root/bin/createuser.sh,实现如下功能:

使用一个用户名做为参数,如果指定参数的用户存在,就显示其存在,否则添加之;并生成8位随机口令并存在一个文件中,初步提示改口令,显示添加的用户的id号等信息

#!/bin/bash
# ------------------------------------------
# Filename: useradd.sh 
# Revision: null
# Date: 2017-09-11 21:47:22
# Author: 赵东
# Email: [email protected]
# Website: null
# Description: new file
# ------------------------------------------
for i in {1..10};do
        pw=`cat /dev/urandom |tr -dc [[:alnum:][:graph:]]|head -c 8` 
        #生成8位随机字符密码
    useradd user$i &> /dev/null
    if [ $? -eq 0 ];then
        echo $pw | passwd --stdin user$i &> /dev/null
        echo "user user$i password is $pw"
    else
        echo "user$i already exist"
    fi
done
#for i in {1..10};do userdel -r user$i;done  删除生成的用户

本题重点:

生成指定长度的随机数

cat /dev/urandom |tr -dc [[:alnum:][:graph:]]|head -c 8

 /dev/urandom中包含了无数个随机字符,常用于随机数的生成,这里我们只需要保留其中的英文和数字,从而截取前8个字符

从标准输入设置用户密码

echo string | passwd --stdin username &> /dev/null


例题二:编写脚本/root/bin/checkint.sh,判断用户输入的参数是否为正整数

#!/bin/bash
# ------------------------------------------
# Filename: checkint.sh 
# Revision: null
# Date: 2017-09-11 20:54:50
# Author: 赵东
# Email: [email protected]
# Website: null
# Description: new file
# ------------------------------------------
read -p "Please input a number: " num
if [[ $num =~ ^[1-9]+[0-9]*$ ]];then
    echo "true"
else
    echo "false";exit 20
fi

本题重点:

有时候越简单的问题,越让人迷惑,比如判断一个数是否为正整数技术分享

而事实上,正整数只是不包括负号‘-’小数点‘.’且开头不为0的数字的集合,这样想起来就很容易表达了,所以正整数的表达方式如下

    [[ $num =~ ^[1-9]+[0-9]*$ ]]



例题三:/etc/rc.d/rc3.d目录下分别有多个以K开头和以S开头的文件;分别读取每个文件,以K开头的输出为文件加stop,以S开头的输出为文件名加start,如K34filename stop 

#!/bin/bash
# ------------------------------------------
# Filename: startorstop.sh 
# Revision: null
# Date: 2017-09-12 08:43:15
# Author: 赵东
# Email: [email protected]
# Website: null
# Description: new file
# ------------------------------------------
ls /etc/rc.d/rc3.d/ | while read filename;do
case $filename in
K*)
    echo "$filename start"
    ;;
S*)
    echo "$filename stop"
    ;;
esac
done

本题重点:

①while的特殊用法:以行为单位遍历文件内容和遍历指定目录下的文件名

用法一: 遍历文件内容  

     while read line;do     

               循环体

     done < 文件路径

其中line为自定义变量,表示文件的行

用法二:配合管道进行遍历,管道前可接命令,如果有多个命令,则用“;”隔开(超好用!!

     ls  /path/dirname | while read filename;do

                循环体

     done

case判断语句中的判断条件支持glob风格的通配符,例如以下常用几种:

          *:任意长度字符

        ?:任意单个字符

         []:任意范围内的单个字符

         a|b:a或b




例题四:打印九九乘法表

#!/bin/bash
# ------------------------------------------
# Filename: 99.sh 
# Revision: null
# Date: 2017-08-25 00:49:26
# Author: zhaodong
# Email: [email protected]
# Website: null
# Description: new file
# ------------------------------------------
echo "99乘法表"
for i in `seq 1 9`;do
    for j in `seq 1 $i`;do
        echo -en "${i}X${j}=$[$i*$j]\t"
    done
    echo
done

本题重点:

如何输出指定范围内的数字或字母???

情况一:没有引用变量

{1..100} {a..z}

情况二:引用变量值

`seq 1 $num`   `seq a $alpha`   (  注意:seq 是一个命令,所以引用命令结果需要加``或$()   )




例题五:

后续六个字符串:efbaf275cd、4be9c40b8b、44b2395c46、f8c8873ce0、b902c16c8b、ad865d2f63是通过对随机数变量RANDOM随机执行命令:

echo $RANDOM|md5sum|cut –c1-10后的结果,请破解这些字符串对应的RANDOM值

#!/bin/bash
# ------------------------------------------
# Filename: md5.sh 
# Revision: null
# Date: 2017-09-12 21:15:21
# Author: 赵东
# Email: [email protected]
# Website: null
# Description: new file
# ------------------------------------------
read -p "Please input your passwd: " md5_pwd
i=1
while [ $i -le 60000 ];do   #穷举60000次
    rdm_num=$RANDOM
    a=`echo ${rdm_num}|md5sum|cut -c1-10`
    if [ $a == $md5_pwd ];then
        result=`echo $rdm_num`
        break
    else
        let i++
        continue
    fi
done
echo "result= " $result
unset i md5_pwd




例题六:

编写服务脚本/root/bin/testsrv.sh,完成如下要求

(1) 脚本可接受参数:start, stop, restart, status

(2) 如果参数非此四者之一,提示使用格式后报错退出

(3) 如是start:则创建/var/lock/subsys/SCRIPT_NAME, 并显示“启动成功”

考虑:如果事先已经启动过一次,该如何处理?

(4) 如是stop:则删除/var/lock/subsys/SCRIPT_NAME, 并显示“停止完成”

考虑:如果事先已然停止过了,该如何处理?

(5) 如是restart,则先stop, 再start

考虑:如果本来没有start,如何处理?

(6) 如是status, 则如果/var/lock/subsys/SCRIPT_NAME文件存在,则显示“SCRIPT_NAMEis running...”

如果/var/lock/subsys/SCRIPT_NAME文件不存在,则显示“SCRIPT_NAME is stopped...”

其中:SCRIPT_NAME为当前脚本名

#!/bin/bash
# ------------------------------------------
# Filename: testsrv.sh 
# Revision: null
# Date: 2017-09-13 22:12:10
# Author: 赵东
# Email: [email protected]
# Website: null
# Description: new file
# ------------------------------------------
. /etc/init.d/functions      #调用函数
filename=`echo /var/lock/subsys/testsrv.sh`   #设置文件名
ls $filename &> /dev/null && exist=true || exist=false #检查文件是否存在
if [ $# -eq 1 ];then  #判断位置参数是否为一个
    if [ "$1" == "start" ]||[ "$1" == "stop" ]||[ "$1" == "restart" ]||[ "$1" == "status" ];then #判断位置参数的值
        case $1 in
        start)
            if [ "$exist" == "false" ];then
                touch $filename
                action "successfull start it" true
            elif [ "$exist" == "true" ];then
                action "Already running..." false
            fi
            ;;
        stop)
            if [ "$exist" == "true" ];then
                rm -rf $filename
                action "successfull stop it" true
            elif [ "$exist" == "false" ];then
                                action "failed stop it" false
            fi
            ;;
        restart)
            if [ "$exist" == "false" ];then
                action "Stopping it:" false
                touch $filename
                echo "starting..."
                action "Restart successfull" true
            elif [ "$exist" == "true" ];then
                rm -rf $filename
                echo "stopping..."
                touch $filename
                echo "starting..."
                action "Restart successfull" true
            fi
            ;;
        status)
            if [ "$exist" == "true" ];then
                echo "`basename $filename` is running..."
            elif [ "$exist" == "false" ];then
                echo "`basename $filename` is stopped..."
            fi
        esac
    else
        echo "usage: `basename $filename` {start|stop|restart|status} "
        exit 1
    fi
else
    echo "Useage is: `basename $filename` {arg} "
    exit 2
fi

本题重点:

函数的调用

当在脚本中引用函数文件中的函数时,正确步骤如下:

步骤1: . /source   函数文件名        f-----执行函数文件(之所以使用这种方式是为了避免进入二级bash从而影响变量的使用)

步骤2: 函数名                                -----调用函数




例题七:

编写脚本/root/bin/copycmd.sh

(1) 提示用户输入一个可执行命令名称

(2) 获取此命令所依赖到的所有库文件列表

(3) 复制命令至某目标目录(例如/mnt/sysroot)下的对应路径下;如:/bin/bash ==> /mnt/sysroot/bin/bash

/usr/bin/passwd==> /mnt/sysroot/usr/bin/passwd

(4) 复制此命令依赖到的所有库文件至目标目录下的对应路径下:如:/lib64/ld-linux-x86-64.so.2 ==> /mnt/sysroot/lib64/ld-linux-x86-64.so.2

(5)每次复制完成一个命令后,不要退出,而是提示用户键入新的要复制的命令,并重复完成上述功能;直到用户输入quit退出

#!/bin/bash
# ------------------------------------------
# Filename: copycmd.sh 
# Revision: null
# Date: 2017-09-14 20:04:12
# Author: 赵东
# Email: [email protected]
# Website: null
# Description: new file
# ------------------------------------------
while true;do
 read -p "Please Input a command(Input "q" or "quit" can be quit): " com
 command_exist=`which $com &> /dev/null;echo $?`   #判断命令是否存在的变量,存在为0
 if [ "$com" == "q" ]||[ "$com" == "quit" ] ;then   #1.判断是否用户是否想退出
     break
 elif [ `echo $command_exist` != 0 ];then            #2.判断命令是否存在
     echo -e "\033[1;31mCommand $com unexist\033[0m"
     continue
 else
     binary=`which $com | tail -1`     #二进制文件路径
     libfile=`ldd $binary | cut -d‘>‘ -f2|grep  /|cut -d‘(‘ -f1` #所有库文件
     路径
     dirname=/mnt/sysroot`dirname $binary`    #二进制文件目标目录
     echo -e "\033[1;32m1.The list of "$com" dependence lib files is:\033[0m"   
     echo "$libfile"                         #3.显示所有库文件                                                
         if [ -e /mnt/sysroot$binary ];then #4.判断二进制文件是否已拷贝 
             echo -e "\033[1;31mCommand already copied\033[0m"
         else
             mkdir -p $dirname
             cp -a $binary $dirname       #5.复制二进制文件到目标目录
             echo -e "\033[1;32m2.Binary files copy successfull\033[0m\n$binary===========>/mnt/sysroot$binary"
             echo -e "\033[1;32m3.Copying lib files:\033[0m"
             for i in `echo $libfile`;do    #5.遍历库文件,并依次复制库文件
                 mkdir -p /mnt/sysroot`dirname $i`  #创建新的库目录
                 cp -a $i /mnt/sysroot`dirname $i`
                 echo -e "$i===========>/mnt/sysroot${i}\n"  
             done
             echo -e "\033[1;32mLib files copy successfull\033[0m"
         fi

  fi
done

本体重点:

①显示指定命令的二进制文件

which command  | tail -1     为啥要截最后一行呢??因为命令可能存在别名,比如下边这种情况

[[email protected] ~]# which ls
alias ls=‘ls --color=auto‘
        /bin/ls

②截取指定命令的所有库文件

ldd `which command | tail -1 ` | cut -d‘>‘ -f2|grep /|cut -d‘(‘ -f1


以上是关于linux脚本进阶例题解析的主要内容,如果未能解决你的问题,请参考以下文章

Linux基础之bash脚本进阶篇-函数

Linux基础之bash脚本编程进阶篇-选择执行语句(if,case)

❥十大排序算法❥爆肝两万字保姆级教程(文字解析+图解+代码实现+例题)

树莓派进阶之路 (033) - 开机启动自定义脚本

Android 进阶——系统启动之Android init.rc脚本解析

Android 进阶——系统启动之Android init.rc脚本解析