Shell编程笔记-语法示例
2016-07-01 16:54
567 查看
先来一个简单的shell程序: $ cat example #!/bin/sh #This is to show what a example looks like. echo "Our first example" echo # This inserts an empty line in output. echo "We are currently in the following directory." /bin/pwd echo echo "This directory contains the following files" /bin/ls shell结构: 1. #!指定执行脚本的shell 2. #注释行 3. 命令和控制结构 创建shell程序的步骤: 第一步:创建一个包含命令和控制结构的文件。 第二步:修改这个文件的权限使它可以执行。 使用chmod u+x 第三步:执行,使用“sh example” 一个纯粹使用命令写的Shell cat sysinfo.sh #! /bin/sh #auto mail for system info /bin/date +%F >> /tmp/sysinfo echo "disk info:" >> /tmp/sysinfo /bin/df -h >> /tmp/sysinfo echo >> /tmp/sysinfo echo "online users:" >> /tmp/sysinfo /usr/bin/who | /bin/grep -v root >> /tmp/sysinfo #除了root外的用户 echo >> /tmp/sysinfo echo "memory info:" >> /tmp/sysinfo /usr/bin/free -m >> /tmp/sysinfo echo >> /tmp/sysinfo #write root /usr/bin/write root < /tmp/sysinfo && /bin/rm /tmp/sysinfo #crontab -e # 0 9 * * 1-5 script Shell变量: 是shell传递数据的一种方法,用来代表每个取值的符号名。 临时变量:是shell程序内部定义的,其使用范围仅限于定义它的程序,对其它程序不可见。包括:用户自定义变量、位置变量。 永久变量:是环境变量,其值不随shell脚本的执行结束而消失。 永久变量: echo $PATH echo $LANG echo $SHELL 用户自定义变量: 由字母或下划线开头,由字母、数字或下划线序列组成,并且大小写字母意义不同。变量名长度没有限制。在使用变量值时,要在变量名前加上前缀“$”。 设置和使用变量 设置变量:习惯上用大写字母来命名变量。变量名只能以字母表中的字符开头,不能用数字。 变量赋值:赋值号“=”两边应没有空格。定义时赋值,如NUM=1 将一个命令的执行结果赋给变量,如:TIME=`date` 将一个变量赋给另一个变量,如:A =$B 使用echo命令查看变量值。例如:echo $A TIME=$(date +%F) , echo $TIME 列出所有的变量: # set 包含多个字的变量: $ NAME=Mike Ron 运行时出错,应改为: $ NAME="Mike Ron" 或$NAME='Mike Ron' 单引号和双引号的区别:、 ABC="$NAME Junior" ABC='$NAME Junior' echo $ABC $NAME Junior 单引号之间的内容原封不动地指定给了变量。 如果是双引号,将使用命令运行结果作为变量值。 删除变量: unset NAME 位置变量和特殊变量 Shell解释执行用户命令时,将命令行的第一个部分作为命令名,其它部分作为参数。由出现在命令行上的位置确定的参数称为位置参数。 例如: ls -l file1 file2 file3 $0 这个程序的文件名ls -l $1 是file1 $2 是file2 $n 这个程序的第n个参数值,n=1-9 一个简单的自动化备份脚本 sh autobak.sh /dirs #----------------------------------------------------------- cat autobak.sh #! /bin/sh #backup files by date +%Y%m%d DATE='/bin/date' /bin/tar -cf /home/raini/视频/shellExample/backup/$1.$DATE.tar $1 > /dev/null 2>> /home/raini/视频/shellExample/backup/$1.bak.log #这里没有指定具体的tar执行目录,用$1表示命令行参数赋值.不看/dev/null的内容。2>> /backup/$1.bak.log将错误日志输入到log. /bin/gzip /home/raini/视频/shellExample/backup/$1.$DATE.tar #gzip进行压缩 if [ $? -eq 0 ] then echo "$1 $DATE backup successfully" >> /home/raini/视频/shell example/backup/$1.bak.log else echo "ERROR: failure $1 $DATE backup!" >> /home/raini/视频/shellExample/backup/$1.bak.log fi #crontab -e #0 3 * * 2,5 /bin/sh ./autobak.sh /script 特殊变量 #----------------------------------------------------------- $* 这个程序的所有参数 $# 这个程序的参数个数 $$ 这个程序的PID $! 执行上一个后台命令的PID $? 执行上一个命令的返回值 ; echo $? 返回0表示执行成功,非0失败 特殊变量使用实例 cat special.var #! /bin/sh #test special variable 单引号 #Usage: sh -x special.var file01 file02 echo '$# is:' $# echo '$* is:' $* echo '$? is:' $? echo '$$ is:' $$ echo 'S0 is:' $0 echo 'S2 is:' $2 read命令 #----------------------------------------------------------- :从键盘读入数据,赋给变量 如:read USERNAME read 的例子: cat read #! /bin/sh read first second third echo "the first parameter is $first" echo "the second parameter is $second" echo "the third parameter is $third" $ sh -x read 注:-x显示出脚本的运行步骤 + read first second third 注:如果输入的参数多于3个,那第个以后的参数都会被视为最后一个参数的一部份被传送 expr 命令 #----------------------------------------------------------- Shell变量的算术运算: expr命令:对-整数-型变量进行算术运算 例如:expr 3 + 5 注:要有空格 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 #! /bin/sh #"if ... else" usage $ pgrep mysql #Using this program to show your system's services. echo "Now, the web services of this Linux system will be detect..." echo #Detect www service web=`/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 start fi #----------------------------------------------------------- cat test.sh #!/bin/sh if [ $# -ne 2 ]; then # $#参数个数 -ne测试整数是否不相等 echo "Not enough parameters" exit 0 #如果参数不符合就退出执行 fi if [ $1 -eq $2 ]; then #-eq测试整数是否相等 echo "$1 equals $2" elif [ $1 -lt $2 ]; then echo "$1 littler than $2" elif [ $1 -gt $2 ]; then echo "$1 greater than $2" #-gt测试int1是否大于 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 #! /bin/sh echo "please input a file name:" read file_name if [ -d $file_name ] #-d file 指定文件是否目录 then echo "$file_name is a directory" elif [ -f $file_name] #-f file 指定文件是否常规文件 then echo "$file_name is a common file" elif [ -c $file_name -o -b $file_name ] #-c是否为二进制文件 then echo "$file_name is a device file" else echo "$file_name is an unknown file" fi 多个条件的联合: -a:逻辑与,仅当两个条件都成立时,结果为真。 -o:逻辑或,两个条件只要有一个成立,结果为真。 for…done语句 #----------------------------------------------------------- 格式:for 变量 in 名字表 do 命令列表 done 例子: #!/bin/sh for DAY in Sunday Monday Tuesday Wednesday Thursday Friday Saturday do echo "The day is : $DAY" done awk信息截取工具 #----------------------------------------------------------- awk -F 域分隔符‘命令’ -F指定分隔符,不指定默认空格 raini@biyuzhe:~$ grep root /etc/passwd #$ ps -le | grep hadoo root:x:0:0:root:/root:/bin/bash 示例: 1、检测系统中UID为0的用户 awk -F: '$3==0 {print $6}' /etc/passwd #:分隔符,‘执行的命令’,/etc/passwd 读取的文件 2、检测系统中密码为空的用户 awk -F: 'length($2)==0 {print $1}' /etc/shadow ps -le | grep sshd | awk '$1==4 {print $14}' #--------------------长脚本--------------------------------------- cat userinfo.sh read username /bin/grep $username /etc/passwd > /dev/null 2> /dev/null if [ $? -eq 0 ] #执行成功返回0 then /bin/echo "username is : $username" else /bin/echo "user $username does not exist" exit 1 fi /bin/echo # list /etc/passwd info #$相当于 grep ^root:x /etc/passwd | awk -F: '$1=="root" {print $5}' userinfo=`/bin/grep ^$username:x /etc/passwd` userid=`/bin/echo $userinfo | /usr/bin/awk -F : '{print $3}'` groupid=`/bin/echo $userinfo | /usr/bin/awk -F : '{print $4}'` homedir=`/bin/echo $userinfo | /usr/bin/awk -F : '{print $6}'` shell=`/bin/echo $userinfo | /usr/bin/awk -F : '{print $7}'` # get group name from GID grouptmpname=`cat /etc/group | /bin/grep :x:$groupid` grouppname=`/bin/echo $grouptmpname | /usr/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 members info:" #get group members groups=`/usr/bin/groups $username` /bin/echo $groups /bin/echo #get login info userlogin=`/usr/bin/who | /bin/grep $username` if [ "$userlogin" != "" ] then /bin/echo "$username is online" else /bin/echo "$username NOT logged in" fi for的例子,杀死某用户的所有进程 #----------------------------------------------------------- cat killuser.sh #! /bin/sh #The script to kill logined user. # kill `ps -aux | grep test | awk '{ print $2 }'` username="$1" #$1是位置变量,awk里的$是划分的部分 /bin/ps -aux | /bin/grep $username | awk '{ print $2 }' > /tmp/temp.pid killid='cat /tmp/temp.pid' for PID in $killid do /bin/kill -9 $PID 2> /dev/null #都kill掉,有错误信息直接放到null done select 变量in 关键字 #----------------------------------------------------------- do ? command 1 ?... ... ? command n done select把关键字中的每一项做成类似表单,以交互的方式执行do和done之间的命令。 select例子 cat select #! /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 case例子 cat case #! /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 #----------------------------------------------------------- cat select.case #!/bin/bash #"select" "case" Usage echo "a is 5,b is 3.Please select you method:" a=5 b=3 select var in "a+b" "a-b" "a*b" "a/b" do break done case $var in "a+b") echo 'a+b='`expr $a "+" $b`;; "a-b") echo 'a-b='`expr $a "-" $b`;; "a*b") echo 'a*b='`expr $a "*" $b`;; "a/b") echo 'a/b='`expr $a "/" $b`;; *) echo "input error..." esac while语句,格式: #----------------------------------------------------------- while 条件 do 命令 done while例子 #!/bin/sh num=1 while [ $num -le 10 ] do SUM=`expr $num \* $num` echo $SUM num=`expr $num + 1` done 免交互录入用户密码 #----------------------------------------------------------- useradd shedon echo 123456 | passwd --stdin shedon #直接设置用户密码 cat useradd.sh #!/bin/sh #Author: Sam #The script to add user #/etc/passwd info echo "please input username:" read name echo "please inpu 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 m=`expr $m +1` done #----------------------------------------------------------- cat deluser.sh #!/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 #----------------------------------------------------------- #! /bin/sh num=1 while [ $num -le 10 ] do SUM=`expr $num \* $num` echo $SUM num=`expr $num + 1` done until语句,格式: #----------------------------------------------------------- until 条件 do 命令 done until类似while循环,不同的是until是条件返回值为 假时才继续执行。 cat until #!/bin/sh until [ -x /etc/inittab ] do /bin/ls -l /etc/inittab exit 0 done cat read.until #----------------------------------------------------------- #!/bin/bash #"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, 用于分别处理每个参数,移出去的参数不再可用 cat shift #!/bin/sh if [ $# -le 0 ] then echo "Not enough parameters" exit 0 fi sum=0 while [ $# -gt 0 ] do su=`expr $sum + $1` shift done echo $sum 函数应用 函数的定义: #----------------------------------------------------------- 函数名() { 命令序列 } 函数的调用:不带() 函数名 参数1 参数2 … 函数中的变量: #----------------------------------------------------------- 变量均为全局变量,没有局部变量 函数中的参数:调用函数时,可以传递参数,在函数中用$1、$2…来引用 cat function HELP() { echo "Usage: sh function \$1 \$2 \$3" } if [ $# -ne 3 ] then HELP else echo "thank for your input, the three arguments is 1 2 3. " fi Shell 脚本调试 #----------------------------------------------------------- sh -x script 这将执行该脚本并显示所有变量的值。 sh -n script 不执行脚本只是检查语法的模式,将返回所有语法错误。 sh 脚本 1、对脚本有r权限 2、对脚本所在目录有rx权限 脚本 1、对脚本有rx权限 2、对脚本所在目录有rx权限
相关文章推荐