魏蓝

以梦为马

导航

shell脚本进阶shift和select

1.shift:解决参数过多问题,将参数装进一个列表,每shift一下,就将列表整体前移,shift默认为1.

范例:用shift批量创建用户

#!/bin/bash
if [ $# -eq 0 ];then
        echo "Usage: `basename $0` user1 user2 ..."
        exit
fi


while [ "$1" ];do
        if id $1 &> /dev/null;then
                echo $1 is exist
        else
                useradd $1
                echo "$1 is created"
        fi
        shift
done
echo "all user is created"

 

 

 

 

 

 

 2.while read

读入一行,逐行处理

例:读入一行,输出一行

root@ubuntu1804:/data# while read line; do echo $line;done

 

 例:读入并打印到文件中

root@ubuntu1804:/data# while read line;do echo $line >> /root/test.org;done

 

 例:标准输入重定向实现逐行处理

root@ubuntu1804:/data# while read line;do echo $line;done << /etc/issue

例:用管道实现逐行处理

root@ubuntu1804:/data# cat /etc/passwd | while read line;do echo $line;done

 

 例:1)显示df设备名及占有率

root@ubuntu1804:/data# df |sed -nr  "/\/dev\/sd/s/^([^ ]+) .* ([0-9]+)%.*/\1 \2/p"

 

 2)逐行处理并发邮件

while true;do
        df |sed -nr  "/\/dev\/sd/s/^([^ ]+) .* ([0-9]+)%.*/\1 \2/p" | while read DEV USE;do [ $USE -gt 80 ] && echo "$DEV will be full,use:$USE" | mail -s "warning" 925724962@qq.com;done
sleep 1
done

例:考试成绩逐行处理

#!/bin/bash
cat score.txt | tr ':' ' ' | while read name score;do
                                        if [ $score -gt 90 ];then
                                                echo $name is excellent
                                        else
                                                echo $name is low
                                        fi
                                done

 

 

3.1)注意:管道符”|“前后会开启子进程

例子:读入变量输出

[root@centos7 data]# echo weilan | read X;echo $X

 

 发现什么都没有输出,要想将变量X输出,则需将管道后的命令放在一个进程里,用”{}“

[root@centos7 data]# echo weilan | { read X;echo $X ; }
weilan

当然小括号”()“也可以:

[root@centos7 data]# echo weilan | (read X;echo $X)
weilan

2)我们再重述大括号”{}“和”()“的区别,小括号”()“是对一串命令重新开一个子进程进行执行。大括号”{}“是在当前进程执行:

()和{}内的命令都是以”;“隔开;

()最后一个命令可以不用分号;

{}最后一个命令需要分号;

()第一个命令不需要和括号间有空格;

{}第一个命令和左边的括号间有空格。

 

4.select:帮我们生成菜单

1)查看select用法.

[root@centos7 data]# help select
select: select NAME [in WORDS ... ;] do COMMANDS; done
    Select words from a list and execute commands.
    
    The WORDS are expanded, generating a list of words.  The
    set of expanded words is printed on the standard error, each
    preceded by a number.  If `in WORDS' is not present, `in "$@"'
    is assumed.  The PS3 prompt is then displayed and a line read
    from the standard input.  If the line consists of the number
    corresponding to one of the displayed words, then NAME is set
    to that word.  If the line is empty, WORDS and the prompt are
    redisplayed.  If EOF is read, the command completes.  Any other
    value read causes NAME to be set to null.  The line read is saved
    in the variable REPLY.  COMMANDS are executed after each selection
    until a break command is executed.
    
    Exit Status:
    Returns the status of the last command executed.

例子:随意创建一个菜单:

[root@centos7 data]# select menu in 备份数据库 清理日志 升级软件 降级软件 删库跑路;do echo $REPLY;done

 

2)增加菜单提示:PS3="xxx" 

[root@centos7 data]# PS3=" 请选择功能(1-5): ";select menu in 备份数据库 清理日志 升级软件 降级软件 删库跑路;do echo $REPLY;done

 例子:点菜菜单

#!/bin/bash
sum=0
PS3="请点菜(1-6):"
select MENU in 北京烤鸭 佛跳墙 小龙虾 羊蝎子 火锅 点菜结束;do
case $REPLY in
1)
        echo $MENU 价格是 100
        let sum+=100
        ;;
2)
        echo $MENU 价格是 88
        let sum+=88
        ;;
3)
        echo $MENU 价格是 66
        let sum+=66
        ;;
4)
        echo $MENU 价格是 166
        let sum+=166
        ;;
5)
        echo $MENU 价格是 200
        let sum+=200
        ;;
6)
        echo "点菜结束,退出"
        break
        ;;
*)
        echo "点菜结束,重新选择"
        ;;
esac
done
echo "总价格是: $sum"

 

 

 

记录于2022/3/4-23:08

posted on 2022-03-04 23:08  魏蓝  阅读(102)  评论(0编辑  收藏  举报