脚本编程:
编程面向过程有如下几种执行方式
顺序执行
选择执行: 如 if, case
循环执行: 如 for, while, until
bash的变量类型:
本地变量
set VAR_NAME=value 设置变量赋值 如: set User=Centos
unset VAR_NAME 撤消变量赋值 如: unset User=Centos
${VAR_NAME}
作用范围:当前shell进程;
局部变量
local VAR_NAME=value 设置变量赋值
unset VAR_NAME 撤消变量赋值
${VAR_NAME}
作用范围:在当前shell进程的局部范围内有效;
环境变量
export VAR_NAME=value 设置变量赋值
unset VAR_NAME 撤消变量赋值
${VAR_NAME}
使用范围:当前shell及其子shell;
位置变量:$1, $2, ...
特殊变量:$$, $?, $#, [email protected], ...
bash命令有执行状态返回值;
$? : 用于保存脚本执行的最后一条命令的状态返回值;
0:表示成功执行;
1-255:表示失败,1,2,127为系统默认保留
[email protected], $*: 所有位置参数;
$#: 位置参数的个数;
注:可以使用exit命令在脚本中自定义脚本执行状态返回值;
如果不定义,脚本执行状态返回值取决于脚本执行结束前最后执行的那个语句的状态;
for 循环使用方式:
for 变量 in 列表; do
语句1;
语句2;
...
done
for 循环使用方式:
for 变量 in {1..100}; do
语句1;
语句2;
...
done
for 循环使用方式:
for 变量 in `seq [起始数 [步进长度] 结束数]`; do
语句1;
语句2;
...
done
例: 查看/var/log各文件类型
#!/bin/bash
#
for Lock in /var/log/* ;do
file $Lock
done
例: 写脚本计算1-100之和
#!/bin/bash
#
Sum=0
for A in {1..100};do
Sum=$[$Sum+$A]
done
echo "Sum:$Sum"
例: 写脚本计算1-100所有奇数之和
#!/bin/bash
#
Sum=0
for A in `seq 1 2 100`;do
Sum=$[$Sum+$A]
done
echo "Sum:$Sum"
条件判断 if 语句
单分支if语句使用方式:
if 条件; then
语句1
语句2
...
fi
例: 写一个脚本,实现如下功能:如果存在,就显示其UID和SHELL;
#!/bin/bash
#
UserName=User1
if id $UserName &> /dev/null;then
grep "^$UserName\>" /etc/passwd | cut -d: -f 3,7
fi
双分支if语句使用方式:
if 条件; then
语句1
语句2
...
else
语句1
语句2
...
fi
例: 写一个脚本:如果指定的用户存在,先说明其已经存在,并显示其ID号和SHELL;
否则,就添加用户,并显示其ID号
#!/bin/bash
#
User=User1
if id $User > /dev/null ;then
grep "^$User\>" /etc/passwd | cut -d: -f3,7
else
useradd $User
echo `grep "^$User\>" /etc/passwd | cut -d: -f3`
fi
bash条件测试:可独立执行的命令不需使用如下测试的方式;
[ expression ]
[[ expression ]]
test expression
expression: 如:数值1 比较符号 数值2
大于:-gt, 例如 $A -gt $B
大于或等于:-ge
等于:-eq
小于:-lt
小于或等于:-le
不等于:-ne
bash有个内置变量:$RANDOM 其值为随机变化
整数测试:
例:写一个脚本,生成两个随机数,比较其大小;显示大数
#!/bin/bash
#
A=$RANDOM
B=$RANDOM
if [ $A -ge $B ] ;then
echo "Max number is $A"
else
echo "Max number is $B"
fi
例: 求200以内所有为3的整数倍的整数之和;
#!/bin/bash
#
Sum=0
for I in {1..200}; do
if [ $[$I%3] -eq 0 ]; then
Sum=$[$Sum+$I]
fi
done
echo "Sum: $Sum."
shift [n]:实现位置参数轮替
例:通过参数传递n个正整数给脚本,求其和;
#!/bin/bash
#
Sum=0
for I in `seq 1 $#`; do
Sum=$[$Sum+$I]
shift
done
echo $Sum
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]"
字符测试:
>: 大于
<: 小于
==: 等于
!=:测试是否不等,不等为真,等为假
=~: 判断左边的字符串是否能够被右边的模式所匹配;通常用于[[]]
如: [[ $opt1 =~ $opt2 ]]
一般做行首、行尾锚定;不要加引号;
例: 写一个脚本通过参数传递一个字符串给脚本,如果传递的字符串“memory”或“Memory”
就以MB为单位显示当前主机的内存信息;否则,就显示/proc/uptime文件的内容。
#!/bin/bash
#
if [[ $1 =~ [Mm]emory$ ]]; then
free -m
else
cat /proc/uptime
fi
例: 写一个脚本:判断当前主机的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
单目测试:
-z $STRING: 为空则为真,不空则为假;
-n $STRING: 为空则为假,不空则真;
例: 写一个脚本,判定用户的shell是否为bash;
#!/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 3
fi
if [ "$Shell" == "/bin/bash" ]; then
echo "Bash User."
Ret=0
else
echo "Not Bash User."
Ret=4
fi
exit $Ret
组合条件测试
-a: 与
-o: 或
!: 非,单目操作符
bash命令组合测试:
&&: 与
||: 或
!: 非
例:写一脚本,给定用户,如果其不存在,就退出脚本。
if ! id $1 &> /dev/null; then
echo "No such user."
exit 3
fi
例:写一个脚本通过参数传递一个字符串给脚本,如果传递的字符串“memory”或“Memory”
就以MB为单位显示当前主机的内存信息;否则,就显示/proc/uptime文件的内容。
#!/bin/bash
#
if [ $1 == "memory" -o $1 == "Memory" ];then
free -m
else
cat /proc/uptime
fi
bash条件判断之多分支if语句:
语法格式:
if 条件1; then
语句1
语句2
...
elif 条件2; then
语句1
语句2
...
elif 条件3; then
语句1
语句2
...
else
语句1
语句2
...
fi
例:判断当前主机的CPU生产商,其信息在/proc/cpuinfo文件中vendor id一行中。
如果其生产商为GenuineIntel,就显示其为Intel公司;
如果其生产商为AuthenticAMD,就显示其为AMD公司;否则,就显示无法识别;
#!/bin/bash
#
Vendor=`grep "vendor_id" /proc/cpuinfo | uniq | cut -d: -f2`
if [[ $Vendor =~ [[:space:]]*GenuineIntel$ ]]; then
echo "intel"
elif [[ $Vendor =~ [[:space:]]*AuthenticAMD$ ]]; then
echo "AMD"
else
echo "Unknown"
fi
例:通过参数传递给脚本一个字符串,如Fedora, Gentoo, Redhat
判断Linux发行版所处理主流发行系列:
如果为fedora, centos, redhat,就显示RedHat;
如果为suse, opensuse,就显示为SUSE;
如果为ubuntu, mint, debian,就显示为Debian;否则,显示为其它或无法识别;
#!/bin/bash
#
if [ $1 == fedora -o $1 == centos -o $1 == redhat ];then
echo "$1 is Redhat"
elif [ $1 == suse -o $1 == opensuse ];then
echo "$1 is Suse"
elif [ $1 == ubuntu -o $1 == mint -o $1 == debian ];then
echo "$1 is Debian"
else
echo "Unknown"
fi
文件测试:
操作符文件路径:
-f : 测试其是否为普通文件,即ls -l时文件类型为-的文件;
-d : 测试其是否为目录文件,即ls -l时文件类型为d的文件;
-e : 测试文件是否存在;存在为真,否则为假;
-r : 测试文件对当前用户来说是否可读;
-w: 测试文件对当前用户来说是否可写;
-x: 测试文件对当前用户来说是否可执行;
-s: 测试文件大小是否不空,不空则真,空则假;
例: 如果/tmp/test10不存在,就创建之;
if [ ! -e /tmp/test10 ];then
mkdir /tmp/test10
fi
短路操作:只要前半段已经可以决定最终结果,后半段就不再运算;
与运算:
真 && 真 = 真
真 && 假 = 假
假 && {真|假} = 假
或运算:
假 || 0 = 0
假 || 1 = 1
真 || =1
例:使用短路操作运算,测试/tmp/test10文件是否存在,若存在则退出,不存在则创建
[ -e /tmp/test10 ] || mkdir /tmp/test10
文中如有错误之处,欢迎大家指教,谢谢!
bash脚本编程之条件判断、条件测试,布布扣,bubuko.com