bash编程: 位置变量
$1, $2, $3, $4, ...
写一个脚本:计算N以内所有奇数的和以及所有偶数的和;分别显示之;N是通过参数传递过来的正整数;
#!/bin/bash
#
EvenSum=0
OddSum=0
for I in `seq 1 $1`;do
if [ $[$I%2] -eq 1 ]; then
OddSum=$[$OddSum+$I]
else
EvenSum=$[$EvenSum+$I]
fi
done
echo "EvenSum: $EvenSum."
echo "OddSUm: $OddSum."
echo "Sum: $[$EvenSum+$OddSum]"
shift [n]:实现位置参数轮替;
例子:通过参数传递n个正整数给脚本,求其和;
#!/bin/bash
#
Sum=0
for I in `seq 1 $#`; do
Sum=$[$Sum+$1]
shift
done
echo $Sum
练习,写一个脚本,完成以下要求:
1、添加10个用户user1, user2, ..., user10;但要先判断用户是否存在,不存在而后再添加;
2、添加完成后,显示一共添加了几个用户;当然,不能包括因为事先存在而没有添加的;
3、最后显示当前系统上共有多少个用户;
#!/bin/bash
#
Count=0
for I in {1..10}; do
if id user$I &> /dev/null; then
echo "user$I exists."
else
useradd user$I
echo "Add user$I successfully."
Count=$[$Count+1]
fi
done
echo "Add $Count new users."
echo "Total users: `wc -l /etc/passwd | cut -d' ' -f1`."
bash字符测试:
>: 大于
<: 小于
==: 等于
=~: 判断左边的字符串是否能够被右边的模式所匹配;通常用于[[]];
[[ $opt1 =~ $opt2 ]]
一般做行首、行尾锚定;不要加引号;
单目:
-z $STRING: 为空则为真,不空则为假;
-n $STRING: 为空则为假,不空则真;
例子:写一个脚本,判定用户的shell是否为bash;
[ "$Shell" == "/bin/bash" ]
#!/bin/bashs
hell=`grep "^$1:" /etc/passwd | cut -d: -f7`
if [ "$Shell" == "/bin/bash" ]; then
echo "Bash User."
Ret=0
else
echo "Not Bash User."
Ret=9
fi
exit $Ret
改进版:
#!/bin/bash
#
Shell=`grep "^$1:" /etc/passwd | cut -d: -f7`
if [ -z $Shell ]; then
echo "No such user or User's shell is null."
exit 10
fi
if [ "$Shell" == "/bin/bash" ]; then
echo "Bash User."
Ret=0
else
echo "Not Bash User."
Ret=9
fi
exit $Ret
例子:根据用户shell的结束符是否为sh来判定其是否为登录用户:
#!/bin/bash
#
Shell=`grep "^$1:" /etc/passwd | cut -d: -f7`
if [ -z $Shell ]; then
echo "No shell."
exit 3
fi
if [[ "$Shell" =~ sh$ ]]; then
echo "Login User."
Ret=0
else
echo "None Login User."
Ret=4
fi
exit $Ret
写一个脚本:
判断当前主机的CPU生产商,其信息在/proc/cpuinfo文件中vendor id一行中。
如果其生产商为GenuineIntel,就显示其为Intel公司;
否则,就显示其为AMD公司;
#!/bin/bash
#
Vendor=`grep "vendor_id" /proc/cpuinfo | uniq | cut -d: -f2`
if [[ "$Vendor" =~ [[:space:]]*GenuineIntel$ ]]; then
echo "Intel"
else
echo "AMD"
fi
练习:写一个脚本
通过参数传递一个字符串给脚本,如果传递的字符串为“memory”或“Memory”,就以MB为单位显示当前主机的内存信息;
否则,就显示/proc/uptime文件的内容。
#!/bin/bash
#
if [[ $1 =~ [Mm]emory$ ]]; then
free -m
else
cat /proc/uptime
fi
bash文件测试:
操作符 文件路径
-f: 测试其是否为普通文件,即ls -l时文件类型为-的文件;
-d: 测试其是否为目录文件,即ls -l时文件类型为d的文件;
-e: 测试文件是否存在;存在为真,否则为假;
-r: 测试文件对当前用户来说是否可读;
-w: 测试文件对当前用户来说是否可写;
-x: 测试文件对当前用户来说是否可执行;
-s: 测试文件大小是否不空,不空则真,空则假;
例子:给定一个路径,判断
如果为普通文件,显示之;
如果为目录,显示之;
否则,说无法识别;
#!/bin/bash
#
if [ ! -e $1 ]; then
echo "No such file."
exit 7
fi
if [ -f $1 ]; then
echo "Common file."
elif [ -d $1 ]; then
echo "Directory."
else
echo "Unknown file."
fi
bash的特殊参数:$0: 脚本名称;
/tmp/script.sh
basename $0
写一个脚本:可以接受一个参数,其使用形式如下:
script.sh {start|stop|restart|status}
如果参数为start,创建空文件/var/lock/subsys/script,并显示“Starting script successfully.”;
如果参数为stop,则删除文件/var/lock/subsys/script,并显示“Stop script finished.”;
如果参数为restart,则删除文件/var/lock/subsys/script后重新创建,并显示“Restarting script successfully.”;
如果参数为status,那么:
如果/var/lock/subsys/script文件存在,则显示为“script is running.”
否则,则显示为“script is stopped.”
其它任何参数:则显示“script.sh {start|stop|restart|status}”
进一步:修改start的机制为:
如果参数为start,且/var/lock/subsys/script文件不存在,则创建空文件/var/lock/subsys/script,并显示“Starting script successfully.”;
否则,显示“script is already running.”
进一步:修改stop的机制为:
如果参数为stop,且/var/lock/subsys/script文件存在,则删除文件/var/lock/subsys/script,并显示“Stop script finished.”;
否则,显示“script is stopped yet.”
#!/bin/bash
if [[ $# -eq 1 ]];then
if [[ $1 == start ]];then
if [ ! -e $dir/script ];then
echo >> $dir/script
echo "Starting script successfully."
else
echo "script is already running."
fi
elif [[ $1 == stop ]];then
if [ -e $dir/script ];then
rm $dir/script
echo "Stop script finished."
else
echo "script is stopped yet."
fi
elif [[ $1 == restart ]];then
if [ -e $dir/script ];then
rm $dir/script
echo >> $dir/script
echo "Restarting script successfully."
else
echo >> $dir/script
echo "Restarting script successfully."
fi
elif [[ $1 == status ]];then
if [ -e $dir/script ];then
echo "script is running."
else
echo "script is stopped."
fi
else
echo "script.sh {start|stop|restart|statu}"
fi
else
echo "script.sh {start|stop|restart|status}"
fi
练习:写一个脚本
给定一个文件:
如果是一个普通文件,就显示之;
如果是一个目录,亦显示之;
否则,此为无法识别之文件;
#!/bin/bash
if [ -f $1 ];then
echo "$1"
elif [ -d $1 ];then
echo "$1"
else
echo "unknown file."
fi
练习:写一脚本
能接受一个参数(文件路径)
判定:此参数如果是一个存在的文件,就显示“OK.”;否则就显示"No such file."
#!/bin/bash
if [ -e $1 ];then
echo "OK."
else
echo "No such file."
fi
练习:写一个脚本,完成以下任务
1、使用一个变量保存一个用户名;
2、删除此变量中的用户,且一并删除其家目录;
3、显示“用户删除完成”类的信息;
#!/bin/bash
USER=$1
if grep "\<$USER\>" /etc/passwd &> /dev/null;then
userdel -r $USER
echo "$USER is removed successfully."
else
echo "$USER not exist."
fi
写一个脚本:
1、添加10个用户user1到user10,密码同用户名;但要求只有用户不存在的情况下才能添加;
#!/bin/bash
for I in `seq 1 10`;do
if grep "\<user$I\>" /etc/passwd &> /dev/null;then
echo "user$I exist."
else
useradd user$I
echo "user$I" | passwd --stdin user$I
fi
done
2、删除添加的用户。
#!/bin/bash
for I in `seq 1 10`;do
if grep "\<user$I\>" /etc/passwd &> /dev/null;then
userdel -r user$I
echo "user$I has been removed."
else
echo "user$I not exist."
fi
done
bash知识点:组合条件测试
-a: 与
-o: 或
!: 非,单目操作符
A=3
UID>=1, UID<=499
bash测试:
bash命令
[]
[[]]
test
bash命令组合测试:
&&: 与
||: 或
!: 非
写一脚本,给定用户,如果其不存在,就退出脚本。
if ! id $1 &> /dev/null; then
echo "No such user."
exit 6
fi
if [ `id -u $1` -eq `id -g $1` ]; then
echo "Good Guy"
else
echo "Bad Guy"
fi
短路操作:只要前半段已经可以决定最终结果,后半段就不再运算;
与运算:
真 && 真 = 真
真 && 假 = 假
假 && {真|假} = 假
或运算:
假 || 0 = 0
假 || 1 = 1
真 || 0或1 = 1
[ -e /tmp/test10 ] || mkdir /tmp/test10
id $UserName &> /dev/null || useradd $UserName
! id $UserName &> /dev/null && useradd $UserName || echo "$UserName exists."
id $UserName &> /dev/null && echo "$UserName exists." || useradd $UserName