Shell脚本编程

简单的shell程序

shell结构:

1.#!指定执行脚本的shell

2.#注释行

3.命令和控制结构

创建shell程序的步骤:

第一步:创建一个包含命令和控制结构的文件。

第二步:修改这个文件的权限使他可以执行。使用 chmod u+x

第三步:执行 ./emample(也可以使用 “sh example”执行)

Shell变量

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

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

临时变量是shell程序内部定义的,其使用范围仅限于定义它的程序,对其他程序不可见。包括:用户自定义变量、位置变量。永久变量是环境变量,其值不随shell脚本的执行结束而消失。

用户自定义变量

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

在使用变量值时,要在变量名前加上前缀“$”。

设置和使用变量

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

变量赋值:赋值号“=”两边应没有空格。

定义时赋值,如NUM=1

将一个命令的执行结果赋给变量,如:TIME='date'

将一个变量赋给另一个变量,如:A=$B

使用echo命令查看变量值。如:echo $A

列出所有变量:

# 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

特殊变量

$* 这个程序的所有参数

$# 这个程序的参数个数

$$ 这个程序的PID

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

$? 执行上一个命令的返回值 -> 0  非0

Shell命令

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

如:read USERNAME

expr命令

Shell变量的算术运算:

expr命令:对整数型变量进行算术运算

例如: expr 3 + 5

  expr $var1 - 5

  expr $var1 / $var2

  expr $var3 \* 10 (乘法)

复杂的expr命令

复杂的运算:

  # expr `expr 5 + 7` / 3

将运算结果赋值给变量:

  var4=`expr $var1 / $var2`

变量测试语句

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

格式:

  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]

流程控制语句

if/else

#!/bin/sh
if [ $# -ne 2 ]; then
 echo "Not enough parameters"
 exit 0
fi
if [ $1 -eq $2 ]; then
 echo "$1 equals $2"
elif [ $1 -gt $2 ]; then
 echo "$1 greater than $2"
elif [ $1 -lt $2 ]; then
 echo "$1 littler than $2"
fi
#!/bin/sh

echo "please input a file name:"
read file_name
if [ -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 unkown file"
fi

多个条件的联合

-a:逻辑与,仅当两个条件都成立时,结果为真。

-o:逻辑或,两个条件只要有一个成立,结果为真。

exit语句:退出程序执行,并返回一个状态码,返回码为0表示正常退出,非0表示非正常退出。

例如:exit 0

for ... done 语句

格式: for 变量 in 名字表
        do
            命令列表
        done
#!/bin/sh

for DAY in Sunday Monday Tuesday Wendesday Thursday Friday Saturday
do
        echo "The day is : $DAY"
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

实例:踢出登录的用户

#!/bin/sh
# The script to kill logined user.

username="$1"

/bin/ps aux | /bin/grep $username | /bin/awk '{ print $2 }' > /tmp/temp.pid

killid=`cat /tmp/temp.pid`

for PID in $killid
do
        /bin/kill -9 $PID 2> /dev/null
done

 

select 变量  in 关键字

do

  command 1

  command n

done

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

#!/bin/sh
# "select usage"

echo "What is your favourite OS?"

select var in "Linux" "Unix" "Windows" "Other"
do
        break
done

echo "You have selected $var"

case...esac语句,格式:

case  变量  in

  字符串1) 命令列表1

      ;;

  字符串n)命令列表n

      ;;

esac

#/bin/sh

echo "*********************************"
echo "please select your operation:"
echo "press c to copy"
echo "press d to delete"
echo "press b to backup"
echo "*********************************"
read op
case $op in
        c)
                echo "your selection is copy"
        ;;
        d)
                echo "your selection is delete"
        ;;
        b)
                echo "your selection is backup"
        ;;
        *)
                echo "invalide selection"
esac

while语句,格式:

  while  条件

  do

    命令

  done

#!/bin/sh

num=1
while [ $num -le 10 ]
do
        sum=`expr $num \* $num`
        echo $sum
        num=`expr $num + 1`
done

实例:批量添加用户脚本

#!/bin/sh
# Author: Simon <E-mail: simon@aliyun.com>
# The script to add user

# /etc/passwd info
echo "please input username:"
read name
echo "please input number:"
read num
n=1
while [ $n -le $num ] 
do
        /usr/sbin/useradd $name$n
        n=`expr $n + 1`
done

# /etc/shadow info
echo "please input the password:"
read passwd
m=1
while [ $m -le $num ]
do
        echo $passwd | /usr/bin/passwd --stdin $name$m > /dev/null
        m=`expr $m + 1`
done

批量删除用户脚本

#!/bin/sh

echo "please input username:"
read name
echo "please input number:"
read num
sum=0
while [ $sum -lt $num ]
do
        sum=`expr $sum + 1`
        /usr/sbin/userdel -r $name$sum
done

until语句,格式:

  until 条件

  do

    命令

  done

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

#!/bin/sh
# "read" "until" usage

echo "press Y/y to stop..."

read input

until [ "$input" = "Y" ] || [ "$input" = "y" ]
do
        echo "error input,please try again..."
        read input
done

echo "stop here!"

跳出循环:break和continue

break:跳出整个循环

continue:跳出本次循环,进行下次循环

 

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

#/bin/sh

if [ $# -le 0 ]
then
 echo "no enough parameters"
 exit 0
fi
sum=0
while [ $# -gt 0 ]
do 
        sum=`expr $sum + $1`
        shift
done
echo $sum

函数应用

函数的定义:

  函数名()

{

  命令序列

}

函数的调用:不带()

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

函数中的变量:

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

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

Shell脚本调试

sh -x script

这将执行该脚本并显示所有变量的值。

sh -n script

不执行脚本只是检查语法的模式,将返回所有语法错误。

 

普通用户执行脚本

sh 脚本

1、对脚本有r权限

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

直接执行脚本

1、对脚本有rx权限

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

 

posted on 2017-08-04 23:41  gimin  阅读(257)  评论(0)    收藏  举报