当前位置: > shell编程 >

shell脚本应用及循环语句

时间:2014-04-29 00:29来源:linux.it.net.cn 作者:IT网





Shell脚本应用及循环语句

一.bash通配符:

   1. ?//任意的单个字符

   2.*//0个或多个字符

   3. []      //区间内的任意一个字符

   4.;       //分割命令,忽略前一个命令的执行结果,继续执行后面的命令

   5.&       //后台执行程序

   6.&&      //前面的命令执行成功,返回值是0,执行后面的命令。

   7.||      //前面的命令执行失败,返回值非0,执行后面的命令。

   8. |       //管道

   9.()      //开启子shell,执行里面的命令

   10.{}      //里面的命令在当前shell执行

   11.> >>    //输出重定向

   12.< <<    //输入重定向

   13.$        //定义变量

   14.\        //转义;命令的折行

   15.``       //调用命令的执行结果;不可以嵌套

   16 .-        //连字符;命令的选项的前导, - --

   17. '' //强引用符号;屏蔽特殊字符

      18.""      //弱引用符号;`` $ \ 3个符号屏蔽不了

      19.//表示空操作,返回值永远是0while循环

      20. [:alnum:]//字母+数字

      21[:alpha:] //字母

      22[:lower:]//小写字母

      23[:upper:] //大写字母

      24[:digit:] //十进制数

      25 [:punct:] //符号

      26 [:space:]//空白字符(空格 “tab”

      27 [[:alnum:]] //任意的一个字母或数字[a-Z0-9]

      28 [^[:alnum:]] //取反

           [[:alnum:]!]

变量

1.注意

1=的两边千万不要有空格

2)不要使用$作为变量的名字

3)变量名的长度--256个字符,区分大小写

2.如何引用

1)直接引用:

echo  命令

-e :启用\(反斜线)控制字符(\t \n)的转换

-n :取消换行符

[root@tx1 ~]# echo "123\t234"

123\t234

[root@tx1 ~]# echo -e "123\t234"

123     234

[root@tx1 ~]# echo -e "123\n234"

123

234

[root@tx1 ~]# echo -n "123\t234"

123\t234[root@tx1 ~]#

(2)间接引用

[root@tx1 ~]# a=b

[root@tx1 ~]# b=c

[root@tx1 ~]# echo $a

b

[root@tx1 ~]# echo ${!a}

c

3)变量的作用域

@1在当前的shell里,定义的变量叫做本地变量-局部变量。

@2全局变量-环境变量,export 把局部变量变成全局变量。只作用于子shell

[root@tx1 ~]# x=123

[root@tx1 ~]# echo $x

123

[root@tx1 ~]# bash

[root@tx1 ~]# echo $x

 

[root@tx1 ~]# exit

exit

[root@tx1 ~]# export x

[root@tx1 ~]# bash

[root@tx1 ~]# echo $x

123

 

(4)查看定义的变量

@1.set 查看所有的变量

@2.env 查看全局变量

@3.unset  取消变量 unset+变量名

@4.设置变量为只读: readonly+变量名

 

(5)位置参数$

注:位置参数,从命令行传递给脚本,或者是传递给函数.或者赋职给一个变量.

$0 命令本身

$1 $2 ...... ${10}

$# 参数的个数

$* 所有的参数

 

$@ 所有的参数(需要被” ” 引用

$$ 上一条命令的进程号

$? 上一条命令的返回结果

$_ 上一条命令的最后一个参数

$! 最后一个进入后台的命令的进程号

$() 等同于``

$(()) 等同于$[] 做数学运算的,但是只能算整数

(6)变量的置换

注:用来执行匹配或者是判断变量是否存在。

@1.${变量名:-字符串}:如果变量是空的,那么就返回字符串;否则返回变量的值

@2.${变量名:+字符串}:如果变量有值,那么使用字符串替换变量;否则返回空值

@3.${变量名:=字符串}:如果变量没有值,那么就把字符串赋值给变量;否则返回变量的值

 

@4.${变量名:?提示信息}:如果变量没有值,那么返回提示信息

@1.

[root@tx1 ~]# echo $a

[root@tx1 ~]# echo ${a:-123}

123

[root@tx1 ~]# b=abc

[root@tx1 ~]# echo ${b:-123}

Abc

 

@2.

[root@tx1 ~]# echo ${a:+123}

[root@tx1 ~]# echo ${b:+123}

123

 

@3.

[root@tx1 ~]# echo $a

[root@tx1 ~]# echo $b

abc

[root@tx1 ~]# echo ${a:=123}

123

[root@tx1 ~]# echo $a

123

[root@tx1 ~]# echo ${b:=123}

abc

[root@tx1 ~]# echo $b

Abc

 

@4.

[root@tx1 ~]# unset a

[root@tx1 ~]# echo ${a:?}

bash: a: parameter null or not set

[root@tx1 ~]# echo ${a:?没有设置变量}

bash: a: 没有设置变量

(7)变量的匹配模式

#:从变量的值的头部开始最小匹配,然后删除

## :从变量的值的头部开始最大匹配,然后删除

%  :从变量的值的尾部开始最小匹配,然后删除

%% :从变量的值的尾部开始最大匹配,然后删除

:num1:num2 :截取变量的值,num1是开始的位置,num2是截取出来几位;0是第一个字符

@1.

[root@tx1 ~]# echo ${pth#*/}

usr/bin/local/bin/all

[root@tx1 ~]# echo ${pth##*/}

all

@2.

[root@tx1 ~]# echo ${pth%/*}

/usr/bin/local/bin

[root@tx1 ~]# echo ${pth%%/*}

 

[root@tx1 ~]#

@3.

[root@tx1 ~]# echo ${pth:0:6}

/usr/b

[root@tx1 ~]# echo ${pth:3:6}

r/bin/

三.If语句

1.单分支if语句.

if [ 条件表达式 ];   then

       命令;...

fi

注:条件满足的时候,就会运行then后面的语句,不满足就直接退出判断语句

 

2.双分支if语句

if [ 条件表达式 ];then

命令;...

   else

命令;...

   fi

注:等条件满足的时候就会运行then后面的语句,条件不满足的时候就运行else后面的语句。

3.条件表达式(man test

1字符串的判断

str1  = str2 检查str1str2是否相同

str1 != str2 检查str1str2是否不同

str1 <  str2 检查str1是否小于str2

str1 >  str2 检查str1是否大于str2

-n   str1    检查str1的长度是否大于0

-z   str1    检查str1的长度是否为0

=~:判断左边的字符串是否能够被右边的模式所匹配[[ "$opt1" =~ pattern ]],  注:判断字符串的时候,字符串要用""包起来(更详细的man test

 

(2)整数的判断

-eq 等于

-ge  大于等于

-gt   大于

-le  小于等于

-lt   小于

-ne  不等于

3文件的判断

        -b file   判断是否存在且为块文件

        -c file 判断是否存在且为字符文件

        -d file 判断是否存在且为目录文件

        -e file   判断文件是否存在

        -f file   判断文件是否存在且为一个普通文件

        -h file 判断是否存在且为符号链接

        -r file 判断是否存在且可读

        -s file 判断是否存在且不为空

        -w file 判断是否存在且可写

        -x file  判断是否存在且可执行

        -O file 判断是否存在且用户为当前用户

        -G file 判断是否存在且组为当前组

 

(4)条件语句

与 -a

if [ 表达式1 -a 表达式2 ]

 

或 -o

if [ 表达式1 -o 表达式2 ]

 

非 !

if [ ! 表达式 ]

[[ 表达式1 && 表达式2 ]]  == -a

[[ 表达式1 || 表达式2 ]]  == -o

[[ ! 表达式 ]]      == !

if 表达式

   then

   command

elif 表达式

   then

   command

elif 表达式

   then

   command

......

else

   command

fi

 

(5)多重判断

 

1.

注:read -p

-t  超时时间    -t 3(秒)

-s  输入没有回显,(密码)

[root@tx1 ~]# vim tx1.sh

#!/bin/bash

#这是一个判断文件类型的脚本

if [ -b /dev/hda1 ]

       then

       echo "块设备"

fi

 

if [ -d /etc ]

       then

       echo "目录"

fi

if [ -e /etc/passwd ]

       then

       echo "普通文件"

 

fi

[root@tx1 ~]# ./tx1.sh

块设备

目录

普通文件

2

#!/bin/bash

#这是一个判断用户是否存在的脚本

 

read -p "请输入一个用户名:" uname

if [ "$uname" = "" ]

       then

      echo "error"

else

       if grep "^\<$uname\>" /etc/passwd &> /dev/null

               then

               echo "这个用户存在"

       else

               echo "这个用户不存在"

       fi

fi

3if的嵌套)

注:为终端加密

[root@tx1 ~]# vim /etc/bashrc

read -p "请输入用户名:" uname

if [ "$uname" = "root" ]

       then

       read -p "请输入密码:" pass

       if [ "$pass" = "123" ]

               then

               echo "welcome root"

       else

               exit 1

       fi

else

       exit 2

fi

打开一个新的终端后

请输入用户名:root

请输入密码:123

welcome root

[root@tx1 ~]#

4

#!/bin/bash

使用双重条件判断用户名和密码

read -t 5 -p "username: " uname

read -s -p "password: " pass

echo

 

if [ "$uname" = "root" -a "$pass" = "123" ]

       then

       echo "welcome root"

else

       echo "go out"

fi

5

#!/bin/bash

#判断一个用户的类型

read -p "请输入一个用户名:" uname

id=`grep "^\<$uname\>" /etc/passwd | cut -d : -f 3 `

if [ "$uname" = "" ]

      then

  echo "error"

elif [ $id -ge 500 ]

      then

  echo "$uname 是普通用户"

elif [ $id -lt 500 -a $id -ge 1 ]

      then

  echo "$uname 是系统用户"

      else

  echo "$uname 是超级用户"

fi

[root@tx1 ~]# ./tx5.sh

请输入一个用户名:root

root 是超级用户

[root@tx1 ~]# ./tx5.sh

请输入一个用户名:tx

tx 是普通用户

[root@tx1 ~]# ./tx5.sh

请输入一个用户名:bin

bin 是系统用户

[root@tx1 ~]# ./tx5.sh

请输入一个用户名:

error

四.case 多分支判断

语法:

case $变量 in

   value1)

   commands

   ;;

   value2)

   commands

   ;;

   ......

   *)

   commands

   ;;

esac

1.

注:例如人的年龄: 婴儿 ,1-9 幼儿1-19 少年20-29 青年30-39 中年40-老年

#!/bin/bash

判断人的年龄段

read -p "请输入一个人的年龄:" age

case $age in

       0)

       echo "婴儿"

       ;;

       [1-9])

       echo "幼儿"

       ;;

       1[0-9])

       echo "少年"

       ;;

       2[0-9])

       echo "青年"

       ;;

       3[0-9])

       echo "中年"

       ;;

       *)

       echo "老年"

       ;;

esac

[root@tx1 ~]# ./t1.sh

请输入一个人的年龄:3

幼儿

[root@tx1 ~]# ./t1.sh

请输入一个人的年龄:67

老年

[root@tx1 ~]# ./t1.sh

请输入一个人的年龄:20

青年

 

五.For循环

注:for循环    事先提供一个元素列表,而后,使用变量去遍历此元素列表,每访问一个元素,就执行一次循环体,直到元素访问完毕
1.语法:

for 变量 in 变量列表

do

   commands

done

1. for循环输出三个数

#!/bin/bash

for i in "$*"

do

       echo $i

done

 

for j in "$@"

do

       echo $j

done

[root@tx1 ~]# ./t3.sh 1 2 3

1 2 3

1

2

3

2.把 /usr/share/doc/ 下所有的index.html复制到 /tmp/index/目录下/tmp/index/  不确定是否存在。

#!/bin/bash

if [ -d /tmp/index ]

       then

       num=1

       for i in $(find /usr/share/doc -name index.html)

       do

               /bin/cp $i /tmp/index/index.html.$num

               num=$(($num+1))

       done

else

       mkdir /tmp/index

       num=1

       for i in $(find /usr/share/doc -name index.html)

       do

               /bin/cp $i /tmp/index/index.html.$num

               num=$(($num+1))

       done

fi

六.While语句

语法:

while [ 表达式 ]

do

   commands

   更新表达式

done

 

表达式的作用:判定循环是否执行。

表达式的返回值为真, $?=0,执行命令

表达式的返回值是假的,结束循环。

true  返回值永远是真的。

1.批量创建5个用户

[root@tx1 ~]# cat t1.txt

tx1

tx2

tx3

tx4

tx5

[root@tx1 ~]# cat  t6.sh

#!/bin/bash

while read line

do

uname=`echo $line`

useradd $uname

echo $uname | passwd $uname --stdin

done < /root/t1.txt

2.信号捕捉

注:信号捕捉trap1 2 9 15 信号9是捕捉不了的。

#!/bin/bash

#信号捕捉

 

trap "echo 进程还在继续" 1

 

while :

do

       echo "hello"

       sleep 3

done

[root@tx1 ~]# ps -a

 PID TTY          TIME CMD

18810 pts/2    00:00:00 bash

18813 pts/2    00:00:00 sleep

18814 pts/1    00:00:00 ps

[root@tx1 ~]# kill -1 18810

 

[root@tx1 ~]# ./t7.sh

hello

hello

hello

hello

进程还在继续

hello

七.Until语句

语法:

until [ 表达式 ]

do

   commands

   更新表达式

done

 

表达式的作用:判定循环是否执行。

   表达式的返回值为假的时候,执行循环,$? 0

   表达式的返回值为真的时候,结束循环

1.

#!/bin/sh

 

a=10;

until [[ $a -lt 0 ]];do

echo $a;

((a--));

done;

[root@tx1 ~]# ./t8.sh

10

9

8

7

6

5

4

3

2

1

0

八.shiftbreakcontinue

1

#!/bin/bash

until [ $# -eq 0 ]

do

echo $*

shift

done

[root@tx1 ~]# ./tt1.sh 1 2 3 4 5 6

1 2 3 4 5 6

2 3 4 5 6

3 4 5 6

4 5 6

5 6

6

2.break跳出循环

#!/bin/bash

for i in `seq 1 2`

do

  for j in `seq 1 3`

  do

       echo $j

       if [ $j -eq 2 ]

               then

               break   #跳出当前循环

       fi

done

done

[root@tx1 ~]# ./tt2.sh

1

2

1

2

 

3

#!/bin/bash

for i in `seq 1 10`

do

  for j in `seq 1 3`

  do

       echo $j

       if [ $j -eq 2 ]

               then

               break 2  #跳出第2层循环

       fi

  done

done

[root@tx1 ~]# ./tt3.sh

1

2

4 (continue结束本次循环)

#!/bin/bash

for i in `seq 1 3`

do

  for j in `seq 1 3`

  do

      if [ $j -eq 2 ]

       then

       continue    #结束本次循环

      fi

      echo $j

  done

done

[root@tx1 ~]# ./tt4.sh

1

3

1

3

1

3

5

#!/bin/bash

for i in `seq 1 3`

do

  for j in `seq 1 3`

  do

      if [ $j -eq 2 ]

       then

       continue 2  #结束第2层的本次循环

      fi

      echo $j

  done

done

 

[root@tx1 ~]# ./tt5.sh

1

1

1

 
(责任编辑:IT)
------分隔线----------------------------
栏目列表
推荐内容