您的位置:首页 > 运维架构 > Shell

shell脚本入门之if-then、for循环

2013-07-20 11:58 281 查看
在脚本中经常使用到变量,在bash编程中,有本地变量,局部变量、
环境变量、位置变量、特殊变量等。
本地变量的作用范围是当前shell进程。
局部变量的作用范围是当前shell的局部范围内有效。
环境变量的作用范围是当前shell及其子shell。
位置变量:为脚本引用参数用如$1表示脚本的第一个参数,$2为第二个。
特殊变量:
$0,命令本身;
$$,当前shell的PID;
$?,上个命令的返回代码;
$#,脚本共有多少个参数;
$@,把脚本的参数全部列出,分别列出;以"$1" "$2" … "$n" 的形式输出所有参数;
$*,把脚本的参数全部列出,当做一个整体列出;以"$1 $2 … $n"的形式输出所有参数;
设置变量:
set Var_name=value
显示变量:
echo ${Var_name}
取消变量:
unset Var_name
导出为环境变量:
export Var_name
shell脚本中进行算术运算:+ - * /
shell不支持浮点数,结果中的浮点数会被圆整为整数:1.23和1.99都等于1
假如:A=5,B=9,
$[$A+$B]
$(($A+$B))
let C=$A+$B
C=`expr $A + $B`,注意变量和运算符之间有空格。

在bash中最基本的结构化命令类型是if-then语句。单分支if语句如下:
if condition
then
commands
fi
如果if后面的条件不成立或命令的退出状态返回值为1,then后面的命令
将不会被执行。
#!/bin/bash
file=$1
if [ -e $1 ] ; then
echo "$1 exists."
fi
if语句可以通过对如下内容进行判断或比较,如果满足条件就执行后面的内容,不满
足则退出或其他操作。

if后面的判断条件的格式可以是以下几种:
1.test condition
2.[ expression ]
3.[[ expression ]]
4.bash命令
用法如下:
if test condition ; then
语句1
语句2
......
fi

if [ expression ]; then
语句1
语句2
.....
fi

if command ; then
语句1
语句2
.....
fi

1、整数比较:
A、B为整数,注意:A、B和表示符以及[]之间有空格,否则为语法错误。
[ A -eq B ] A等于B
[ A -ne B ] A不等于B
[ A -gt B ] A大于B
[ A -lt B ] A小于B
[ A -le B ] A小于等于B
[ A -ge B ] A大于等于B
假如A=10 、 B=10,
if [ $A -eq $B ]
then
echo "$A is equal to $B"
fi
2、字符串比较:
注意事项:
1)、在脚本中 > < 将被理解为输出/入重定向,所以需要进行转义处理
2)、在test命令中,大写字母小于小写字母与sort命令排序相反。test使用标准的ASCII
排序。
[ str1 = str2 ]str1等于str2
[[ str1 == regexp ]]str1能否被regexp匹配,
[[ str1 =~ regexp ]]同上
[ str1 != str2 ]str1不等于str2
[ str1 \< str2 ]str1小于str2
[ str1 \> str2 ]str1大于str2
[ -n str ]检查str是否为空,空为假,不空为真
[ -z str ]检查str是否为空,空为真,不空为假
[root@www ifsh]# more iftest.sh
#!/bin/bash
read -p "Your name please: " Usr
if [[ "$Usr" =~ [Rr]oot ]]
then
echo "hello $Usr"
else
echo "Who are you ?"
fi

3、文件比较:
-f: 测试其是否为普通文件,即ls -l时文件类型为-的文件;
-d: 测试其是否为目录文件,即ls -l时文件类型为d的文件;
-e: 测试文件是否存在;存在为真,否则为假;
-r: 测试文件对当前用户来说是否可读;
-w: 测试文件对当前用户来说是否可写;
-x: 测试文件对当前用户来说是否可执行;
-s: 测试文件大小是否不空,不空则真,空则假;
-O:测试文件是否属于命令发起者;
-G:测试文件是否属于命令发起者的组;
如:如果脚本的参数是文件就cat此文件,如果是目录就ls此目录。其他类型就不处理
[root@www ifsh]# more filetest.sh
#!/bin/bash
file=$1
if [ -f $1 ] ; then
cat $1
elif [ -d $1 ];then
ls $1
else
echo "$1 is unknown."
fi
其他测试条件:
1)组合条件测试,连接多个条件,
-a 与
-o 或
! 非

&& 与
|| 或
! 非
[root@www ifsh]# more ifand.sh
#!/bin/bash
read -p "Your score: " N
if [ $N -ge 80 -a $N -le 90 ] ; then
echo "Level B"
elif [ $N -gt 90 ] && [ $N -le 100 ] ; then
echo "Level A"
else
echo "Level C"
fi
2)检查文件日期:
-nt 比较一个文件是否比另一个文件新。
-ot 比较一个文件是否比另一个文件旧。
[root@www ifsh]# more testnt.sh
#!/bin/bash
file1=/tmp/a
file2=/tmp/b
if [ $file1 -nt $file2 ];then
echo "$file1 is newer"
else
echo "$file2 is newer"
fi
多分支if语句:
语法格式:
if 条件1; then
语句1
语句2
...
elif 条件2; then
语句1
语句2
...
elif 条件3; then
语句1
语句2
...
else
语句1
语句2
...
fi
例如:给出一个用户,根据其Uid判断属于哪一类用户。
#!/bin/bash
read -p "Please chose a username: " USR
if id $USR &> /dev/null; then
Uid=`grep -w "^$USR" /etc/passwd | cut -d: -f3`
if [ $Uid -eq 0 ] ; then
echo "$USR is here"
elif [ $Uid -gt 499 ] ; then
echo "$USR is a common user."
else
echo "$USR is a SystemUser."
fi
fi

在脚本中,可以获取上条命令的执行状态值,正常执行为0,非正常为1-255之间的数值
用户可以自定义命令返回值。

例子:根据用户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
for循环
事先提供一个元素列表,而后使用变量去遍历此列表;每访问一个元素,就执行一次循
环体,直到元素访问完毕。
for Var_name in 元素1 元素2....;do
语句1
语句2
......
done
元素列表的生成方法有
1、逐个给出;{n1..n2}表示序列
如:#!/bin/bash
for I in 1 2 3 4 5; do
let sum+=$I
done ;
echo $sum
-------------
#!/bin/bash
for I in {1..5}; do
let sum+=$I
done
echo $sum (效果跟上面的一样)
2、使用通配符实现文件通配,如:查看/var下文件的类型
#!/bin/bash
for file in /var/* ; do
file $file
done
3、使用命令生成列表:
#!/bin/bash
for I in `seq 1 100`;do
let sum+=$I
done
echo $sum
seq命令:
seq 1 100 输出1到100,
seq 1 2 100 输出1 3 5 7 9 ...99 就是输出从1开始步长为2(间隔为2)直到100

比较经典的一个用法就是计算1到100的和:
计算100以内奇数和偶数的和:
#!/bin/bash
Sum=0
Sum2=0
for I in {1..100}; do
if [ $[$I%2] -eq 0 ];then
Sum=$[$Sum+$I]
else
Sum2=$[$Sum2+$I]
fi
done
echo "偶数和是 $Sum"
echo "奇数和是 $Sum2"
-----------------------------------
#!/bin/bash
let sum=0
for I in $(seq 0 2 100); do
sum=$[$sum+$I]
done
echo "偶数的和是:$sum"
for X in $(seq 1 2 100); do
sum2=$[$sum2+$X]
done
echo "奇数的和是: $sum2"
-----------------------------------
添加用户,如果存在就显示存在,不存在就创建
[root@www forsh]# more adduser.sh
#!/bin/bash
for I in {1..10}; do
if id user$I &> /dev/null ; then
echo "user$I exist."
else
useradd user$I
echo "user$I" | passwd --stdin user$I &> /dev/null
let Count++
echo "user$I added."
fi
done
echo "$Count new comers."

脚本练习题:
1、显示/etc/passwd文件中第1、3、6、12个用户的用户名、ID和shell;
[root@www forsh]# more id.sh
#!/bin/bash

for I in 1 3 6 12 ; do
Uname=`head -$I /etc/passwd | tail -1 | cut -d: -f1`
Uid=`head -$I /etc/passwd |tail -1 | cut -d: -f3`
Gid=`head -$I /etc/passwd | tail -1 | cut -d: -f4`
BaseGrp=`cat /etc/group | grep -w "$Gid" | cut -d: -f1`
if [ $I -eq 1 ] ; then
echo -e "\tThe ${I}st username:$Uname UID:$Uid Group:$BaseGrp"
elif [ $I -eq 3 ]; then
echo -e "\tThe ${I}rd Username:$Uname UID:$Uid Group:$BaseGrp"
else
echo -e "\tThe ${I}th Username:$Uname UID:$Uid Group:$BaseGrp"
fi
done
显示效果为:
The 1st username:root UID:0 Group:root
The 3rd Username:daemon UID:2 Group:daemon
The 6th Username:sync UID:5 Group:root
The 12th Username:operator UID:11 Group:root
知识点:
shift 弹出参数
[root@www forsh]# more t1.sh
#!/bin/bash
echo $1
shift 4
echo $1
shift
echo $1
[root@www forsh]# ./t1.sh 1 2 3 4 5 6 7
1
5
6
给出任意个任意长度的数,计算这几个数的和。
[root@www forsh]# more ta.sh
#!/bin/bash
let sum=0
for I in `echo $*`;do
let sum=$sum+$1
shift
done
echo "$sum"

本文出自 “每天进步1%” 博客,请务必保留此出处http://jackyan.blog.51cto.com/2589874/1253228
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: