Shell编程

来源:互联网 发布:上海php技术总监 编辑:程序博客网 时间:2024/06/10 21:07

1 shell编程语法

1.1 一个简单的shell程序

  

1.2 shell变量

变量:是shell传递数据的一种方法,用来代表每个取值的符号名。

查看系统中所有变量:【set】命令

删除变量:【unset   变量名】


Shell有两类变量:临时变量永久变量

临时变量是shell程序内部定义的,其使用范围仅限于定义它的程序,对其它程序不可见。包括:用户自定义变量、位置变量。

永久变量是环境变量,其值不随shell脚本的执行结束而消失。

1.2.1 用户自定义变量

用户定义的变量由字母或下划线开头,由字母、数字或下划线序列组成,并且大小写字母意义不同。变量名长度没有限制。

在使用变量时,要在变量名前加上前缀【$】。

1.2.2 设置和使用变量

设置变量:习惯上用大写字母来命名变量。变量名只能以字母表中的字符开头,不能用数字。

变量赋值:赋值号【=】两边应没有空格

  • 定义时赋值,如NUM=1
  • 将一个命令的执行结果赋给变量,如:TIME=`date`       (注意这里不是单引号,而是Esc下的键,命令替换符
  • 将一个变量赋给另一个变量,如:A=$B
查看变量:使用echo命令查看变量值。例如:echo  $A

  

双引号和单引号的区别:


1.2.3 位置变量和特殊变量

① 位置变量

Shell解释执行用户名令时,将命令行的第一个部分作为命令名,其它部分作为参数。

由出现在命令行上的位置确定的参数称为位置参数。

例如:【ls  -l   file1  file2 file3】

$0:这个程序的文件名ls  -l

$n:这个程序的第n个参数值,n=1-9

位置变量示例:

[xiaoming@nikikiy shelltest]$ cat exapmle #!/bin/bashecho "this is the first shell"DATE=$(date +%F)ls -l $1 > `pwd`_$DATE.txt[xiaoming@nikikiy shelltest]$ sh exapmle /homethis is the first shell[xiaoming@nikikiy shelltest]$ 

②特殊变量

$*  这个程序的所有参数

$#  这个程序的参数个数

$$  这个程序的PID

$!   执行上一个后台命令的PID

$?   执行上一个命令的返回值(0:表示成功;非0:表示失败)

特殊变量示例:

[xiaoming@nikikiy shelltest]$ pwd/home/xiaoming/shelltest[xiaoming@nikikiy shelltest]$ cat special.var echo '$# is:' $#echo '$* is:' $*echo '$? is:' $?echo '$ $ is:' $ $echo '$0 is:' $0[xiaoming@nikikiy shelltest]$ sh special.var hello world jiaozl 123$# is: 4$* is: hello world jiaozl 123$? is: 0$$ is: 5634$0 is: special.var[xiaoming@nikikiy shelltest]$

1.3 Shell命令

1.3.1  read命令

从键盘读入数据,赋给变量【read  变量名】

示例:【sh -x read.sh】调试执行

[xiaoming@nikikiy shelltest]$ cat read.sh #!/bin/bashread first second thirdecho "the first parameter is $first"echo "the second parameter is $second"echo "the third parameter is $third"[xiaoming@nikikiy shelltest]$ sh read.sh 100 200 300the first parameter is 100the second parameter is 200the third parameter is 300[xiaoming@nikikiy shelltest]$ sh -x read.sh + read first second third100 200 300+ echo 'the first parameter is 100'the first parameter is 100+ echo 'the second parameter is 200'the second parameter is 200+ echo 'the third parameter is 300'the third parameter is 300[xiaoming@nikikiy shelltest]$ 

1.3.2 expr命令

Shell变量的算术运算:

expr 命令:对整型变量进行算术运算(注意:运算数与运算符之间有空格)

例如: 加:【expr 3 + 5】 减:【expr $var1 - 5】 除:【expr  $var1   /   $var2】  乘法:【expr $var3  \* 10】

复杂运算:【expr `expr 5 + 7` /  $var4】   

将运算结果赋予变量:【var4=`expr $var1 / $var2`】

示例:

[xiaoming@nikikiy shelltest]$ cat expr.sh #!/bin/bashread first second thirdecho "the first is $first the second is $second    the third is $third"value1=`expr $first \* $second`echo "the first 乘 the second is $value1"value2=`expr $second + $third / $first`echo "the second + the third / the first is $value2"[xiaoming@nikikiy shelltest]$ sh -x expr.sh + read first second third3 10 39+ echo 'the first is 3 the second is 10         the third is 39'the first is 3 the second is 10         the third is 39++ expr 3 '*' 10+ value1=30+ echo 'the first 乘 the second is 30'the first 乘 the second is 30++ expr 10 + 39 / 3+ value2=23+ echo 'the second + the third / the first is 23'the second + the third / the first is 23[xiaoming@nikikiy shelltest]$ 

1.3.3 变量测试语句test 以及 if

用于测试变量是否相等、是否为空、文件类型等。

格式:【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]

示例: 检测httpd是否启动

[root@nikikiy shelltest]# cat test.apache #!/bin/bashweb=`/usr/bin/pgrep httpd`if [ "$web" != "" ] then        echo "The web service is running"else        echo "The web service is not running"        /etc/rc.d/init.d/httpd startfi[root@nikikiy shelltest]# sh -x test.apache ++ /usr/bin/pgrep httpd+ web='647764856486648764886489649064916492'+ '[' '647764856486648764886489649064916492' '!=' '' ']'+ echo 'The web service is running'The web service is running[root@nikikiy shelltest]# 

1.4 流控制语句

1.4.1 if--elfi--else--fi

-o:逻辑或;-a:逻辑与
exit语句:退出程序执行,并返回一个返回码,返回码为0表示正常退出,非0表示非正常退出;
例如:exit 0

示例1:判断文件类型

[xiaoming@nikikiy shelltest]$ cat if_else #!/bin/bashread file_nameif [ -d $file_name ]; then        echo "$file_name is a directory"elif [ -f $file_name ] then        echo "$file_name is a common file"elif [ -c $file_name -o -b $file_name ]; then        echo "$file_name is a device file"else        echo "$file_name is an unknown file"fi[xiaoming@nikikiy shelltest]$ sh if_else if_elseif_else is a common file[xiaoming@nikikiy shelltest]$ sh if_else /home/home is a directory[xiaoming@nikikiy shelltest]$ 
示例2:判断整型大小
[xiaoming@nikikiy shelltest]$ cat test.sh #!/bin/bashif [ $# -ne 2 ]; then        echo "not enough parameters"        exit 0fiif [ $1 -eq $2 ]; then        echo "$1 equals $2"elif [ $1 -lt $2 ]; then        echo "$1 littler then $2"elif [ $1 -gt $2 ]; then        echo "$1 greater then $2"fi[xiaoming@nikikiy shelltest]$ sh test.shnot enough parameters[xiaoming@nikikiy shelltest]$ sh test.sh 12 34 45not enough parameters[xiaoming@nikikiy shelltest]$ sh test.sh 12 4512 littler then 45[xiaoming@nikikiy shelltest]$ sh test.sh 120 45120 greater then 45[xiaoming@nikikiy shelltest]$ sh test.sh 120 120120 equals 120[xiaoming@nikikiy shelltest]$ 

1.4.2 for--do--done

示例1 :简单输出

[xiaoming@nikikiy shelltest]$ cat for #!/bin/bashfor DAY in Sunday Monday Tuesday Wednesday Thursday Friday Saturday; do        echo "The day is : $DAY"done[xiaoming@nikikiy shelltest]$ sh for The day is : SundayThe day is : MondayThe day is : TuesdayThe day is : WednesdayThe day is : ThursdayThe day is : FridayThe day is : Saturday[xiaoming@nikikiy shelltest]$ 
示例2:剔除用户

[root@nikikiy shelltest]# cat killuser.sh #!/bin/bashusername="$1"/bin/ps aux | /bin/grep $username | /bin/awk '{ print $2 }' > /tmp/temp.pidkillid=`cat /tmp/temp.pid`for PID in $killid; do        /bin/kill -9 $PID 2> /dev/nulldone[root@nikikiy shelltest]# sh killuser.sh brother02已杀死[root@nikikiy shelltest]# sh killuser.sh brother03已杀死[root@nikikiy shelltest]# cat /tmp/temp.pid 7636764077307732[root@nikikiy shelltest]# 

1.4.3 select--do---done

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

示例:

[xiaoming@nikikiy shelltest]$ cat select #!/bin/bashselect var in "Linux" "UNIX" "Windows" "Other"; do        breakdoneecho "You have select $var"[xiaoming@nikikiy shelltest]$ sh select 1) Linux2) UNIX3) Windows4) Other#? 1You have select Linux[xiaoming@nikikiy shelltest]$ 

1.4.4 case--esac

示例:

[xiaoming@nikikiy shelltest]$ cat case #!/bin/bashread opcase $op in        C)                echo "your selection is Copy"        ;;        D)                echo "your selection is Delete"        ;;        B)                echo "your selection is Backup"        ;;        *)                echo "invalide selection"esac[xiaoming@nikikiy shelltest]$ sh case Dyour selection is Delete[xiaoming@nikikiy shelltest]$ sh case sinvalide selection[xiaoming@nikikiy shelltest]$ 

1.4.5 while--do--done

示例1 :

[xiaoming@nikikiy shelltest]$ cat while#!/bin/bashnum=1while [ $num -le 10 ]; do        sum=`expr $num \* $num`        echo $sum        num=`expr $num + 1`done[xiaoming@nikikiy shelltest]$ sh while 149162536496481100[xiaoming@nikikiy shelltest]$ 
示例2:【echo 123456 |  passwd --stdin xiaoming】采用交互式方式设置密码
[root@nikikiy shelltest]# cat useradd.sh #!/bin/bashecho "please input username:"read nameecho "please input number:"read numn=1while [ $n -le $num ]; do        /usr/sbin/useradd $name$n        n=`expr $n + 1`doneecho "please input the password:"read passwdm=1while [ $m -le $num ]; do        echo $passwd | /usr/bin/passwd --stdin $name$m        m=`expr $m + 1`done[root@nikikiy shelltest]# sh useradd.sh please input username:testusersplease input number:2please input the password:123更改用户 testusers1 的密码 。passwd: 所有的身份验证令牌已经成功更新。更改用户 testusers2 的密码 。passwd: 所有的身份验证令牌已经成功更新。[root@nikikiy shelltest]# ls /home | grep testusers?[root@nikikiy shelltest]# ls /home | grep testuserstestusers1testusers2[root@nikikiy shelltest]# 

1.4.6 until--do--done

跳出循环break;跳出本次循环,继续下次循环continue;

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

[xiaoming@nikikiy shelltest]$ cat until.sh #!/bin/bashread inputuntil [ "$input" = "Y" ] || [ "$input" = "y" ]; do        echo "error input, please try again ..."        read inputdoneecho "Stop here!"[xiaoming@nikikiy shelltest]$ sh until.sh s  error input, please try again ...yStop here![xiaoming@nikikiy shelltest]$ 

1.4.7 shift指令

参数左移,每执行一次,参数序列顺次左移一个位置,$#的值减1;

用于分别处理每个参数,移出去的参数不可再用。
示例:

[xiaoming@nikikiy shelltest]$ cat shift #!/bin/bashif [ $# -le 0 ]; then        exit 0fisum=0while [ $# -gt 0 ]; do        sum=`expr $sum + $1`        shiftdoneecho $sum[xiaoming@nikikiy shelltest]$ sh shift 3 45 755[xiaoming@nikikiy shelltest]$ 

1.5 函数

1.5.1 相关语法

函数的定义:

函数名()

{

命令序列

}

函数的调用:不带()

函数名  参数1 参数2 .....

函数中的变量:

变量均为全局变量,没有局部变量

函数中的参数:

调用函数时,可以传递参数,在函数中用$1、$2... 来引用

1.5.2 函数示例

[xiaoming@nikikiy shelltest]$ cat function #!/bin/bashhelp(){        echo "Usage: sh function \$1 \$2 \$3"}if [ $# -ne 3 ]; then        helpelse        echo "thank for your input, the three agruments is 1 2 3."fi[xiaoming@nikikiy shelltest]$ sh function 1 3 5thank for your input, the three agruments is 1 2 3.[xiaoming@nikikiy shelltest]$ sh functionUsage: sh function $1 $2 $3[xiaoming@nikikiy shelltest]$

2 awk命令应用

【awk -F  域分隔符 `命令`】

示例:

①检测系统中UID为0的用户

【awk -F:  '$3==0  {print  $1}'   /etc/passwd】

②检测系统中密码为空的用户

【awk -F:  'length($2)!=0  {print  $1}'  /etc/shadow】
示例:

[xiaoming@nikikiy shelltest]$ cat userinfo.sh #!/bin/bashread username/bin/grep $username /etc/passwd > /dev/null 2> /dev/nullif [ $? -eq 0 ]; then        /bin/echo "username is: $username"else        /bin/echo "user $username does not exist"        exit 1fi/bin/echouserinfo=`/bin/grep ^$username:x /etc/passwd`userid=`/bin/echo $userinfo | /bin/awk -F: '{print $1}'`groupid=`/bin/echo $userinfo | /bin/awk -F : '{print $4}'`homedir=`/bin/echo $userinfo | /bin/awk -F: '{print $6}'`shell=`/bin/echo $userinfo | /bin/awk -F: '{print $7}'`grouptmpname=`cat /etc/group | /bin/grep :x:$groupid`groupname=`/bin/echo $grouptmpname | /bin/awk -F : '{print $1}'`/bin/echo "user id is: $userid"/bin/echo "default group is : $groupname"/bin/echo "home directory is : $homedir"/bin/echo "shell is : $shell"/bin/echo "group memebers info: "groups=`/usr/bin/groups $username`/bin/echo $groups/bin/echouserlogin=`/usr/bin/who | /bin/grep $username`if [ "$userlogin" != "" ]; then        /bin/echo "$username is online"else        /bin/echo "$username NOT logged in"fi[xiaoming@nikikiy shelltest]$ sh userinfo.sh brother03 username is: brother03user id is: brother03default group is : brother01home directory is : /home/brother03shell is : /bin/bashgroup memebers info: brother03 : brother01brother03 NOT logged in[xiaoming@nikikiy shelltest]$

3 Shell脚本调试

【sh -x script】这将执行改脚本,并显示所有变量的值;
【sh -n  script】不执行脚本,只检查语法的模式,将返回所有语法错误

4 普通用户对脚本执行的权限

sh  脚本
①对脚本有r权限
②对脚本所在目录有rx权限


 脚本
①对脚本有rx权限
②对脚本所在目录有rx权限


原创粉丝点击