#!/bin/bash # if [ $# -lt 1 ] ; then echo -e "Usage: $(basename $0) options... USERLIST\n" echo -e " Options: " echo -e " -a, --add: \vAdd some users from USERLIST." echo -e " -d, --delete: \vDelete some users from USERLIST." echo -e " -h, --help: \vPrint help informationn." echo -e " -v, --verbose: \vPrint more informationn about manage users." echo echo -e " USERLIST FORMAT: " echo -e " USERNAME1,USERNAME2,...,USERNAMEN" exit 5 fi
ADDUSER=0 DELUSER=0 DEBUG=0
for I in $(seq $#) ; do if [ $# -ne 0 ] ;then case $1 in -h|--help) echo -e "Usage: $(basename $0) options... USERLIST\n" echo -e " Options: " echo -e " -a, --add: \vAdd some users from USERLIST" echo -e " -d, --delete: \vDelete some users from USERLIST" echo -e " -h, --help: \vPrint help informationn" echo -e " -v, --verbose: \vPrint more informationn about manage users." echo echo -e " USERLIST FORMAT: " echo -e " USERNAME1,USERNAME2,...,USERNAMEN" exit 0 ;; -v|--verbose) DEBUG=1 shift ;; -a|--add) ADDUSERLIST=$2 ADDUSER=1 shift 2 ;; -d|--delete) DELUSERLIST=$2 DELUSER=1 shift 2 ;; *) echo -e "Usage: $(basename $0) options... USERLIST\n" echo -e " Options: " echo -e " -a, --add: \vAdd some users from USERLIST" echo -e " -d, --delete: \vDelete some users from USERLIST" echo -e " -h, --help: \vPrint help informationn" echo -e " -v, --verbose: \vPrint more informationn about manage users." echo echo -e " USERLIST FORMAT: " echo -e " USERNAME1,USERNAME2,...,USERNAMEN" exit 6 ;; esac fi done
if [ $ADDUSER -eq 1 ] ; then for J in $(echo $ADDUSERLIST | tr ',' ' ') ; do if ! id $J &> /dev/null ; then useradd $J &> /dev/null echo $J | passwd --stdin $J &> /dev/null [ $DEBUG -eq 1 ] && echo "Create user $J successfully." else echo "$J exist already." fi done fi
if [ $DELUSER -eq 1 ] ; then for J in $(echo $DELUSERLIST | tr ',' ' ') ; do if id $J &> /dev/null ; then userdel -r $J &> /dev/null [ $DEBUG -eq 1 ] && echo "Delete user $J finished." else echo "$J does not exist yet." fi done fi
while循环结构 while 命令; do 命令; done 在脚本中可以写成下列结构: while CONDITION ; do COMMAND done
until循环结构 until 命令; do 命令; done 在脚本中可以写成下列结构: until CONDITION ; do COMMAND done until循环进入循环条件:CONDITION为假 until循环推出循环条件:CONDITION为真
注意: 1.while CONDITION 相当于 until !CONDITION 2.while和until循环结构中,没有变量自增或自减的变化方法;因此需要使用语句手动给出变量的变化方式;
写一个脚本,使用while或until循环,计算100以内整数的和; #!/bin/bash # declare -i I=0 until [ $I -eq 100 ] ; do let I++ let SUM+=$I done
echo $SUM
#!/bin/bash # declare -i I=0 while [ $I -lt 100 ] ; do let I++ let SUM+=$I done
echo $SUM
循环控制语句: continue: continue [n] 继续 for、while、或 until 循环。 提前结束第N层当前循环,直接进入下一轮条件判断,如果条件判断结果仍然满足循环进入条件,则开启下一轮循环; break break [n] 退出 for、while、或 until 循环 提前结束第N层循环,且不再继续后续循环
while和until的两种特殊循环使用方法: 1.无限循环方法 while true ; do COMMAND done
until false ; do COMMAND done
猜数字游戏: #!/bin/bash # NUMBER=$[RANDOM%100+1] while true ; do read -p "Input a number: " INPTNUM if [ $INPTNUM -gt $NUMBER ] ; then echo "Too big" elif [ $INPTNUM -lt $NUMBER ] ; then echo "Too small" else echo "Yes! you WIN. That's $NUMBER." break fi done
#!/bin/bash # NUMBER=$[RANDOM%100+1] until false ; do read -p "Input a number: " INPTNUM if [ $INPTNUM -gt $NUMBER ] ; then echo "Too big" elif [ $INPTNUM -lt $NUMBER ] ; then echo "Too small" else echo "Yes! you WIN. That's $NUMBER." break fi done
注意:在此类循环结构中需要适当的添加continue或break,使无限循环可控;
2.实现遍历功能的while和until循环结构 while read LINES ; do COMMADN done < /PATH/FORM/SOMEFILES
until ! read LINES ; do COMMADN done < /PATH/FORM/SOMEFILES
注意:在做遍历循环时建议使用for;
select循环结构 select NAME [in 词语 ... ;] do 命令; done select循环也是一种遍历列表的方式创建一个可视化菜单,每个列表中项都有一个数字编号与之对应,供用户选择使用,而用户只需要选择编号即可; select是一种默认无限循环结构;因此必须在循环体中卫select提供退出循环条件,通常可以使用break或exit命令实现; 通常情况下,select循环会和case一起使用,以进行合理的取值判断;
在脚本中实现格式: select VAR-NAME in LIST ; do COMMAND done 写一个脚本,显示以/bin/bash为默认shell的用户的ID信息; #!/bin/bash # select I in $(awk -F : '/\/bin\/bash$/{print $1}' /etc/passwd) quit ; do case $I in quit) exit ;; *) echo "The UID of $I is $(id -u $I)" ;; esac done
函数直接递归调用示例1: 计算某个数字的阶乘; 利用for循环: #!/bin/bash # fact=1 if [ $1 -eq 0 ] ; then echo "0! is $fact" elif [ $1 -eq 1 ] ; then echo "1! is $fact" else for I in $(seq $1) ; do let fact=$[fact*$I] done echo "${1}! is $fact" fi
利用函数递归调用: #!/bin/bash # fact(){ if [ $1 -eq 0 ] || [ $1 -eq 1 ] ; then echo 1 else echo "$[$1*$(fact $[$1-1])]" fi }
echo "${1}! is $(fact $1)"
示例2: 斐波那契数列(黄金分割数列)
1 1 2 3 5 8 13 21 34 55 ...
N=N-1 + N-2
#!/bin/bash # fabonacci(){ if [ $1 -eq 1 ] || [ $1 -eq 2 ] ; then echo -n "1 " else echo -n "$[$(fabonacci $[$1-1])+$(fabonacci $[$1-2])] " fi }
for I in $(seq $1) ; do fabonacci $I done echo
示例三: 汉诺塔
#!/bin/bash # step=0 move(){ let step++ echo "$step: move disk $1 $2 --> $3" }
hanoi(){ if [ $1 -eq 1 ] ; then move $1 $2 $4 else hanoi "$[$1-1]" $2 $4 $3 move $1 $2 $4 hanoi "$[$1-1]" $3 $2 $4 fi }