平时的运维中,shell脚本确实是运维的一大神器,能够帮助很多操作实现自动化操作,但是一些shell脚本的高级用法,我之前也是不知道的,这里我写这篇文章整理一下。

while的特殊用法(遍历文件的每一行)

while read line; do控制变量初始化

  循环体

done < /PATH/FROM/SOMEFILE

或cat /PATH/FROM/SOMEFILE | while read line; do

  循环体

done

依次读取/PATH/FROM/SOMEFILE文件中的每一行,且将行赋值给变量line

select循环与菜单

用法

select variable in list

do

  循环体命令

done

① select 循环主要用于创建菜单,按数字顺序排列的示菜单项将显示在标准错误上,并显示PS3 提示符,等待用户输入

② 用户输入菜单列表中的某个数字,执行相应的命令

③ 用户输入被保存在内置变量 REPLY 中

④ select 是个无限循环,因此要记住用 break 命令退出循环,或用 exit 按 命令终止脚本。也可以按 ctrl+c退出循环

⑤ select 和 经常和 case 联合使用

⑥ 与for循环类似,可以省略 in list, 此时使用位置参量

实例

#!/bin/bash
PS3='Please choose the menu:'
select menu in 米饭 面条 粥 馄饨 quit
do
    case $REPLY in
    1|4)
        echo "the price is 15"
        ;;
    2|3)
        echo "the price is 20"
        ;;
    5)
        break
        ;;
    *)
        echo "no option"
    esac 
done

shell_advance1

循环控制语句

用法

continue [N]:提前结束第N层的本轮循环,而直接进入下一轮判断;最内层为第1层

break [N]:提前结束第N层循环,最内侧为第1层

例:while CONDTITON1; do

  CMD1

if CONDITION2; then

  continue / break

fi

  CMD2

done

案例

#求(1+3+...+49+53+...+100)的和
#!/bin/bash
sum=0
for i in {1..100};do
        [ $i -eq 51 ] && continue
        [ $[$i%2] -eq 1 ] && { let sum+=i;let i++; }
done
echo sum=$sum

循环控制(shift命令)

作用

用于将参数列表list左移指定次数,最左端的那个参数就从列表中删除,其后边的参数继续进入循环

案例

① 创建指定的多个用户

#!/bin/bash
if [ $# -eq 0 ];then
    echo "please input a arg"
    exit 1
else 
    while [ -n "$1" ];do
        useradd $1 &> /dev/null
        shift
    done
fi

② 打印直角三角形的字符

#!/bin/bash
while (( $# > 0 ))
do
        echo "$*"
        shift
done

shell_advance2

循环中可并行执行,使脚本运行更快

for name in 列表 ;do

  {

  循环体

  }&

done

wait

信号捕获

用法

trap ' 触发指令' 信号,自定义进程收到系统发出的指定信号后,将执行触发指令,而不会执行原操作

trap '' 信号,忽略信号的操作

trap '-' 信号,恢复原信号的操作

trap -p,列出自定义信号操作

信号可以3种表达方法:信号的数字2、全名SIGINT、缩写INT

常用信号

1) SIGHUP: 无须关闭进程而让其重读配置文件

2) SIGINT: 中止正在运行的进程;相当于Ctrl+c

3) SIGQUIT: 相当于ctrl+\

9) SIGKILL: 强制杀死正在运行的进程

15) SIGTERM :终止正在运行的进程(默认为15)

18) SIGCONT :继续运行

19) SIGSTOP :后台休眠
9 信号,强制杀死,捕获不住

案例

打印0-3,ctrl+c不能终止,3之后恢复,能终止

#!/bin/bash
trap '' 2
trap -p
for ((i=0;i<3;i++));do
        sleep 1
        echo $i
done
trap '-' SIGINT
for ((i=3;i<10;i++));do
        sleep 1
        echo $i
done

生成随机字符

#生成8个随机大小写字母或数字 
cat /dev/urandom |tr -dc [:alnum:] |head -c 8

生成随机数

#确定范围 
echo $[RANDOM%7] 随机7个数(0-6)
echo $[$[RANDOM%7]+31] 随机7个数(31-37)

echo打印颜色字

echo -e "\033[31malong\033[0m" 显示红色along

echo -e "\033[1;31malong\033[0m" 高亮显示红色along

echo -e "\033[41malong\033[0m" 显示背景色为红色的along

echo -e "\033[31;5malong\033[0m" 显示闪烁的红色along

color=$[$[RANDOM%7]+31]

echo -ne "\033[1;${color};5m*\033[0m" 显示闪烁的随机色along

一些知识点

$0 当前脚本的文件名
$n 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。
$# 传递给脚本或函数的参数个数。
$* 传递给脚本或函数的所有参数。
$@ 传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同
当它们被双引号(" ")包含时,"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;"$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数。
$? 上个命令的退出状态,或函数的返回值。
$$ 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。

版权声明:本文为原创文章,版权归 heroyf 所有
本文链接: https://heroyf.club/2018/09/shell-advanced/


“苹果是给那些为了爱选择死亡的人的奖励”