shell编程

来源:Jeff's Blog Sell 编程

一个简单的shell程序

 1 $ cat example  
2 #!/bin/sh
3 #This is to show what a example looks like.
4 echo "Our first example"
5 echo # This inserts an empty line in output.
6 echo "We are currently in the following directory."
7 /bin/pwd
8 echo
9 echo "This directory contains the following files"
10 /bin/ls

shell结构:
1. #!指定执行脚本的shell
2. #注释行
3. 命令和控制结构
创建shell程序的步骤:
第一步:创建一个包含命令和控制结构的文件。
第二步:修改这个文件的权限使它可以执行。
使用 chmod u+x
第三步:执行
./example
(也可以使用“sh example”执行)

一个纯粹使用命令写的Shell

 1 cat sysinfo.sh  
2 #! /bin/sh
3 #auto mail for system info
4 /bin/date +%F >> /tmp/sysinfo
5 echo "disk info:" >> /tmp/sysinfo
6 /bin/df -h >> /tmp/sysinfo
7 echo >> /tmp/sysinfo
8 echo "online users:" >> /tmp/sysinfo
9 /usr/bin/who | /bin/grep -v root >> /tmp/sysinfo
10 echo >> /tmp/sysinfo
11 echo "memory info:" >> /tmp/sysinfo
12 /usr/bin/free -m >> /tmp/sysinfo
13 echo >> /tmp/sysinfo
14 #write root
15 /usr/bin/write root < /tmp/sysinfo && /bin/rm /tmp/sysinfo
16 #crontab -e

Shell变量
变量:是shell传递数据的一种方法,用来代表每个取值
的符号名。
Shell有两类变量:临时变量和永久变量。
临时变量是shell程序内部定义的,其使用范围仅限于定
义它的程序,对其它程序不可见。包括:用户自定义变
量、位置变量。永久变量是环境变量,其值不随shell脚
本的执行结束而消失。
永久变量:
echo $PATH
echo $LANG
echo $SHELL

用户自定义变量
用户定义的变量由字母或下划线开头,由字母、
数字或下划线序列组成,并且大小写字母意义不
同。变量名长度没有限制。
在使用变量值时,要在变量名前加上前缀“$”。

设置和使用变量
设置变量:习惯上用大写字母来命名变量。变量名只能
以字母表中的字符开头,不能用数字。
变量赋值:赋值号“=”两边应没有空格。
定义时赋值,如NUM=1
将一个命令的执行结果赋给变量,如:TIME=`date`
将一个变量赋给另一个变量,如:A =$B
使用echo命令查看变量值。例如:echo $A
TIME=$(date +%F)

列出所有的变量:
# set
包含多个字的变量:
$NAME=Mike Ron
运行时出错,应改为:
$NAME=“Mike Ron” 或$NAME=‘Mike Ron’

单引号和双引号的区别:
# $ABC=‘$NAME Junior’
# echo $ABC
$NAME Junior
单引号之间的内容原封不动地指定给了变量。
如果是双引号,将使用命令运行结果作为变量值。
删除变量:
# unset NAME

位置变量和特殊变量
Shell解释执行用户命令时,将命令行的第一个
部分作为命令名,其它部分作为参数。由出现
在命令行上的位置确定的参数称为位置参数。
例如:
ls -l file1 file2 file3
$0 这个程序的文件名ls -l
$n 这个程序的第n个参数值,n=1-9

一个简单的备份脚本

 

 1 cat autobak.sh  
2 #! /bin/sh
3 #backup files by date
4 DATE='/bin/date +%Y%m%d'
5 /bin/tar -cf /backup/$1.$DATE.TAR $1 > /dev/null 2>> /backup/$1.bak.log
6 /bin/gzip /backup/$1.$DATE.tar
7 if [ $? -eq 0 ]
8 then
9 echo "$1 $DATE backup successfully" >> /backup/$1.bak.log
10 else
11 echo "ERROR: failure $1 $DATE backup!" >> /backup/$1.bak.log
12 fi
13 #crontab -e

特殊变量

$* 这个程序的所有参数
$# 这个程序的参数个数
$$ 这个程序的PID
$! 执行上一个后台命令的PID
$? 执行上一个命令的返回值

特殊变量使用实例

1 cat special.var  
2 #! /bin/sh
3 #test special variable
4 #Usage: sh special.var file01 file02
5 echo '$# is:' $#
6 echo '$* is:' $*
7 echo '$? is:' $?
8 echo '$ is:' $
9 echo 'S0 is:' $0


Shell命令
read命令:从键盘读入数据,赋给变量
如:read USERNAME

read 的例子:

1 cat read  
2 #! /bin/sh
3 read first second third
4 echo "the first parameter is $first"
5 echo "the second parameter is $second"
6 echo "the third parameter is $third"

sh -x read 注:-x显示出脚本的运行步骤

+ read first second third
注:如果输入的参数多于3个,那第个以后的参数都会被视为最后一个参数的一部份被传送

expr 命令
Shell变量的算术运算:
expr命令:对整数型变量进行算术运算
例如:expr 3 + 5 注:要有空格
expr $var1 - 5
expr $var1 / $var2
expr $var3 \* 10 注:剩法要用转义符

复杂的expr命令
复杂的运算:
expr `expr 5 + 7`/$var4
将运算结果赋予变量:
var4=` expr $var1 / $var2 `

expr 命令

#!/bin/sh  
a=10
b=20
c=30
value1=`expr $a + $b + $c`
echo "The value of value1 is $value1"
value2=`expr $c / $b`
echo "The value of value2 is $value2"
value3=`expr $c \* $b`
echo "The value of value3 is $value3"
value4=`expr $a + $c / $b`
echo "The value of value4 is $value4"

变量测试语句
变量测试语句:用于测试变量是否相等、是否为
空、文件类型等。
格式:
test 测试条件
测试范围:整数、字符串、文件


字符串测试:
test str1=str2 测试字符串是否相等
test str1!=str2 测试字符串是否不相等
test str1 测试字符串是否不为空
test -n str1 测试字符串是否不为空
test -z str1 测试字符串是否为空


整数测试:
test int1 -eq int2 测试整数是否相等
test int1 -ge int2 测试int1是否>=int2
test int1 -gt int2 测试int1是否>int2
test int1 -le int2 测试int1是否<=int2
test int1 -lt int2 测试int1是否<int2

test int1 -ne int2 测试整数是否不相等


文件测试:
test -d file 指定文件是否目录
test -f file 指定文件是否常规文件
test -x file 指定文件是否可执行
test -r file 指定文件是否可读
test -w file 指定文件是否可写
test -a file 指定文件是否存在
test -s file 文件的大小是否非0

变量测试语句一般不单独使用,一般做为if语句
的测试条件,如:
if test -d $1 then

fi
变量测试语句可用[]进行简化,如
test -d $1 等价于
[ -d $1 ]

cat test.apache

 1 #! /bin/sh  
2 #"if ... else" usage
3 #Using this program to show your system's services.
4 echo "Now, the web services of this Linux system will be detect..."
5 echo
6 #Detect www service
7 web=`/usr/bin/pgrep httpd`
8 if [ "$web" !="" ]
9 then
10 echo "The Web service is running."
11 else
12 echo "The Web service is NOT running."
13 /etc/rc.d/init.d/httpd start
14 fi

cat test.sh

 1 #!/bin/sh  
2 if [ $# -ne 2 ]; then
3 echo "Not enough parameters"
4 exit 0
5 fi
6 if [ $1 -eq $2 ]; then
7 echo "$1 equals $2"
8 elif [ $1 -lt $2 ]; then
9 echo "$1 littler than $2"
10 elif [ $1 -gt $2 ]; then
11 echo "$1 greater than $2"
12 fi
 1 #!/bin/sh  
2 if [ $# -ne 2 ]; then
3 echo "Not enough parameters"
4 exit 0
5 fi
6 if [ $1 -eq $2 ]; then
7 echo "$1 equals $2"
8 elif [ $1 -lt $2 ]; then
9 echo "$1 littler than $2"
10 elif [ $1 -gt $2 ]; then
11 echo "$1 greater than $2"
12 fi

流控制语句
流控制语句:用于控制shell程序的流程
exit语句:退出程序执行,并返回一个返回码,返
回码为0表示正常退出,非0表示非正常退出。
例如:exit 0

if …then …fi语句,例如:
#!/bin/sh
if [ -x /etc/rc.d/init.d/httpd ]
then
/etc/rc.d/init.d/httpd restart
fi

更复杂的if语句:
if 条件1 then
命令1
elif 条件2 then
命令2
else
命令3

fi

cat if_else

 

 1 #! /bin/sh  
2 echo "please input a file name:"
3 read file_name
4 if [ -d $file_name ]
5 then
6 echo "$file_name is a directory"
7 elif [ -f $file_name]
8 then
9 echo "$file_name is a common file"
10 elif [ -c $file_name -o -b $file_name ]
11 then
12 echo "$file_name is a device file"
13 else
14 echo "$file_name is an unknown file"
15 fi


多个条件的联合:
-a:逻辑与,仅当两个条件都成立时,结果为真。
-o:逻辑或,两个条件只要有一个成立,结果为真。

for…done语句
格式:for 变量 in 名字表
do
命令列表
done

例子:

1 #!/bin/sh  
2 for DAY in Sunday Monday Tuesday Wednesday Thursday Friday Saturday
3 do
4 echo "The day is : $DAY"
5 done


awk命令应用
awk -F 域分隔符‘命令’
示例:
1、检测系统中UID为0的用户
awk -F: '$3==0 {print $1}' /etc/passwd
2、检测系统中密码为空的用户
awk -F: 'length($2)==0 {print $1}' /etc/shadow

cat userinfo.sh

 

 1 read username  
2 /bin/grep $username /etc/passwd > /dev/null 2> /dev/null
3 if [ $? -eq 0 ]
4 then
5 /bin/echo "username is : $username"
6 else
7 /bin/echo "user $username does not exist"
8 exit 1
9 fi
10 /bin/echo
11 # list /etc/passwd info
12 userinfo=`/bin/grep ^$username:x /etc/passwd`
13 userid=`/bin/echo $userinfo | /bin/awk -F : '{print $3}'`
14 groupid=`/bin/echo $userinfo | /bin/awk -F : '{print $4}'`
15 homedir=`/bin/echo $userinfo | /bin/awk -F : '{print $6}'`
16 shell=`/bin/echo $userinfo | /bin/awk -F : '{print $7}'`
17 # get group name from GID
18 grouptmpname=`cat /etc/group | /bin/grep :x:$groupid`
19 grouppname=`/bin/echo $grouptmpname | /bin/awk -F : '{print $1}'`
20 /bin/echo "user id is : $userid"
21 /bin/echo "default group is : $groupname"
22 /bin/echo "home directory is : $homedir"
23 /bin/echo "shell is : $shell"
24 /bin/echo "group members info:"
25 #get group members
26 groups=`/usr/bin/groups $username`
27 /bin/echo $groups
28 /bin/echo
29 #get login info
30 userlogin=`/usr/bin/who | /bin/grep $username`
31 if [ "$userlogin" != "" ]
32 then
33 /bin/echo "$username is online"
34 else
35 /bin/echo "$username NOT logged in"
36 fi

for的例子,杀死某用户的所有进程

 1 cat killuser.sh  
2 #! /bin/sh
3 #The script to kill logined user.
4 username="$1"
5 /bin/ps aux | /bin/grep $username | /bin/awk '{ print $2 }' > /tmp/temp.pid
6 killid='cat /tmp/temp.pid'
7 for PID in $killid
8 do
9 /bin/kill -9 $PID 2> /dev/null
10 done

select 变量in 关键字
do
? command 1
?... ...
? command n
done
select把关键字中的每一项做成类似表单,以交互的
方式执行do和done之间的命令。

select例子
cat select

1 #! /bin/sh  
2 #"select" Usage
3 echo "What is your favourite OS?"
4 select var in "Linux" "UNIX" "Windows" "Other"
5 do
6 break
7 done
8 echo "You have selected $var"

case…esac语句,格式:
case 变量
in
字符串1) 命令列表1
;;
...
字符串n) 命令列表n
;;
esac

case例子
cat case

 

 1 #! /bin/sh  
2 echo "***********************************"
3 echo "Please select your operation:"
4 echo "Press "C" to Copy"
5 echo "Press "D" to Delete"
6 echo "Press "B" to Backup"
7 echo "***********************************"
8 read op
9 case $op in
10 C)
11 echo "your selection is Copy"
12 ;;
13 D)
14 echo "your selection is Delete"
15 ;;
16 B)
17 echo "your selection is Backup"
18 ;;
19 *)
20 echo "invalide selection"
21 esac

cat select.case

 1 #!/bin/bash
2 #"select" "case" Usage
3 echo "a is 5,b is 3.Please select you method:"
4 a=5
5 b=3
6 select var in "a+b" "a-b" "a*b" "a/b"
7 do
8 break
9 done
10 case $var in
11 "a+b") echo 'a+b='`expr $a "+" $b`;;
12 "a-b") echo 'a-b='`expr $a "-" $b`;;
13 "a*b") echo 'a*b='`expr $a "*" $b`;;
14 "a/b") echo 'a/b='`expr $a "/" $b`;;
15 *) echo "input error..."
16 esac

 

 1 #"select" "case" Usage  
2 echo "a is 5,b is 3.Please select you method:"
3 a=5
4 b=3
5 select var in "a+b" "a-b" "a*b" "a/b"
6 do
7 break
8 done
9 case $var in
10 "a+b") echo 'a+b='`expr $a "+" $b`;;
11 "a-b") echo 'a-b='`expr $a "-" $b`;;
12 "a*b") echo 'a*b='`expr $a "*" $b`;;
13 "a/b") echo 'a/b='`expr $a "/" $b`;;
14 *) echo "input error..."
15 esac

while语句,格式:

while 条件
do
命令
done

cat while

1 #!/bin/sh  
2 num=1
3 while [ $num -le 10 ]
4 do
5 SUM=`expr $num \* $num`
6 echo $SUM
7 num=`expr $num + 1`
8 done

免交互录入用户密码
useradd shedon
echo 123456 | passwd --stdin shedon

cat useradd.sh

 1 #!/bin/sh  
2 #Author: Sam
3 #The script to add user
4 #/etc/passwd info
5 echo "please input username:"
6 read name
7 echo "please inpu number:"
8 read num
9 n=1
10 while [ $n -le $num]
11 do
12 /usr/sbin/useradd $name$n
13 n=`expr $n + 1`
14 done
15 #/etc/shadow info
16 echo "please input the password:"
17 read passwd
18 m=1
19 while [ $m -le $num ]
20 do
21 echo $passwd | /usr/bin/passwd --stdin $name$m
22 m=`expr $m +1`
23 done

cat deluser.sh

1 #! /bin/sh
2 num=1
3 while [ $num -le 10 ]
4 do
5 SUM=`expr $num \* $num`
6 echo $SUM
7 num=`expr $num + 1`
8 done

until语句,格式:

until 条件do命令doneuntil类似while循环,不同的是until是条件返回值为假时才继续执行。

 

1 #!/bin/sh  
2 until [ -x /etc/inittab ]
3 do
4 /bin/ls -l /etc/inittab
5 exit 0
6 done

cat until

cat read.until

 1 #!/bin/bash  
2 #"read" "until" usage
3 echo "Press Y/y to stop..."
4 read input
5 until [ "$input" = "Y" ] || [ "$input" = "y" ]
6 do
7 echo "error input,please try again..."
8 read input
9 doen
10 echo "Stop here!"

跳出循环:break和continue
break:跳出整个循环
continue:跳过本次循环,进行下次循环

shift指令:参数左移,每执行一次,参数序列顺
次左移一个位置,$#的值减1,
用于分别处理每个参数,移出去的参数不再可用

cat shift

 1 #!/bin/sh  
2 if [ $# -le 0 ]
3 then
4 echo "Not enough parameters"
5 exit 0
6 fi
7 sum=0
8 while [ $# -gt 0 ]
9 do
10 su=`expr $sum + $1`
11 shift
12 done
13 echo $sum


函数应用
函数的定义:
函数名()
{
命令序列
}
函数的调用:不带()
函数名
参数1 参数2 …

函数中的变量:
变量均为全局变量,没有局部变量
函数中的参数:调用函数时,可以传递参数,在函
数中用$1、$2…来引用

cat function

 1 HELP()  
2 {
3 echo "Usage: sh function \$1 \$2 \$3"
4 }
5 if [ $# -ne 3 ]
6 then
7 HELP
8 else
9 echo "thank for your input, the three arguments is 1 2 3. "
10 fi

Shell 脚本调试
sh -x script
这将执行该脚本并显示所有变量的值。
sh -n script
不执行脚本只是检查语法的模式,将返回
所有语法错误。

sh 脚本
1、对脚本有r权限
2、对脚本所在目录有rx权限

脚本
1、对脚本有rx权限
2、对脚本所在目录有rx权限


posted @ 2011-11-21 13:58  captain_meng  阅读(749)  评论(0编辑  收藏  举报