Shell编程笔记-语法示例

来源:互联网 发布:飞凡软件 编辑:程序博客网 时间:2024/06/08 10:36
先来一个简单的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/pwdechoecho "This directory contains the following files"/bin/lsshell结构:    1. #!指定执行脚本的shell    2. #注释行    3. 命令和控制结构创建shell程序的步骤:    第一步:创建一个包含命令和控制结构的文件。    第二步:修改这个文件的权限使它可以执行。        使用chmod u+x    第三步:执行,使用“sh example”一个纯粹使用命令写的Shellcat sysinfo.sh#! /bin/sh#auto mail for system info/bin/date +%F >> /tmp/sysinfoecho "disk info:" >> /tmp/sysinfo/bin/df -h >> /tmp/sysinfoecho >> /tmp/sysinfoecho "online users:" >> /tmp/sysinfo/usr/bin/who | /bin/grep -v root >> /tmp/sysinfo #除了root外的用户echo >> /tmp/sysinfoecho "memory info:" >> /tmp/sysinfo/usr/bin/free -m >> /tmp/sysinfoecho >> /tmp/sysinfo#write root/usr/bin/write root < /tmp/sysinfo && /bin/rm /tmp/sysinfo#crontab -e# 0 9 * * 1-5 scriptShell变量:    是shell传递数据的一种方法,用来代表每个取值的符号名。临时变量:是shell程序内部定义的,其使用范围仅限于定义它的程序,对其它程序不可见。包括:用户自定义变量、位置变量。永久变量:是环境变量,其值不随shell脚本的执行结束而消失。永久变量:echo $PATHecho $LANGecho $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%dDATE='/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 ]thenecho "$1 $DATE backup successfully" >> /home/raini/视频/shell example/backup/$1.bak.logelseecho "ERROR: failure $1 $DATE backup!" >> /home/raini/视频/shellExample/backup/$1.bak.logfi#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 file02echo '$# is:' $# echo '$* is:' $*echo '$? is:' $?echo '$$ is:' $$echo 'S0 is:' $0echo 'S2 is:' $2read命令#-----------------------------------------------------------    :从键盘读入数据,赋给变量    如:read USERNAMEread 的例子:cat read#! /bin/shread first second thirdecho "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 - 5expr $var1 / $var2expr $var3 \* 10 注:剩法要用转义符复杂的expr命令复杂的运算:expr `expr 5 + 7`/$var4将运算结果赋予变量:var4=` expr $var1 / $var2 `#-----------------------------------------------------------expr 命令#!/bin/sha=10b=20c=30value1=`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是否>=int2test int1 -gt int2 测试int1是否>int2test int1 -le int2 测试int1是否<=int2test int1 -lt int2 测试int1是否<int2test 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 thenfi变量测试语句可用[]进行简化,如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 serviceweb=`/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#-----------------------------------------------------------cat test.sh#!/bin/shif [ $# -ne 2 ]; then  # $#参数个数  -ne测试整数是否不相等    echo "Not enough parameters"    exit 0         #如果参数不符合就退出执行fiif [ $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 0ifthenfi语句,例如:#!/bin/shif [ -x /etc/rc.d/init.d/httpd ]then/etc/rc.d/init.d/httpd restartfi更复杂的if语句:if 条件1 then命令1elif 条件2 then命令2else命令3fi#-----------------------------------------------------------cat if_else#! /bin/shecho "please input a file name:"read file_nameif [ -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:逻辑或,两个条件只要有一个成立,结果为真。fordone语句#-----------------------------------------------------------格式:for 变量 in 名字表do命令列表done例子:#!/bin/shfor DAY in Sunday Monday Tuesday Wednesday Thursday Friday Saturdaydoecho "The day is : $DAY"doneawk信息截取工具#-----------------------------------------------------------awk -F 域分隔符‘命令’  -F指定分隔符,不指定默认空格raini@biyuzhe:~$ grep root /etc/passwd #$ ps -le | grep hadooroot: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.shread username/bin/grep $username /etc/passwd > /dev/null 2> /dev/nullif [ $? -eq 0 ] #执行成功返回0then    /bin/echo "username is : $username"else    /bin/echo "user $username does not exist"    exit 1fi/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 GIDgrouptmpname=`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 membersgroups=`/usr/bin/groups $username`/bin/echo $groups/bin/echo#get login infouserlogin=`/usr/bin/who | /bin/grep $username`if [ "$userlogin" != "" ]then    /bin/echo "$username is online"else    /bin/echo "$username NOT logged in"fifor的例子,杀死某用户的所有进程#-----------------------------------------------------------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.pidkillid='cat /tmp/temp.pid'for PID in $killiddo    /bin/kill -9 $PID 2> /dev/null #都kill掉,有错误信息直接放到nulldoneselect 变量in 关键字#-----------------------------------------------------------do? command 1?... ...? command ndoneselect把关键字中的每一项做成类似表单,以交互的方式执行dodone之间的命令。select例子cat select#! /bin/sh#"select" Usageecho "What is your favourite OS?"select var in "Linux" "UNIX" "Windows" "Other"do    breakdone    echo "You have selected $var"caseesac语句,格式:#-----------------------------------------------------------case 变量 in    字符串1) 命令列表1    ;;    ...    字符串n) 命令列表n    ;;esaccase例子cat case#! /bin/shecho "***********************************"echo "Please select your operation:"echo "Press "C" to Copy"echo "Press "D" to Delete"echo "Press "B" to Backup"echo "***********************************"read 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#-----------------------------------------------------------cat select.case#!/bin/bash#"select" "case" Usageecho "a is 5,b is 3.Please select you method:"a=5b=3select var in "a+b" "a-b" "a*b" "a/b"do    breakdonecase $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..."esacwhile语句,格式:#-----------------------------------------------------------while 条件do    命令donewhile例子#!/bin/shnum=1while [ $num -le 10 ]do    SUM=`expr $num \* $num`    echo $SUM    num=`expr $num + 1`done免交互录入用户密码#-----------------------------------------------------------useradd shedonecho 123456 | passwd --stdin shedon #直接设置用户密码cat useradd.sh#!/bin/sh#Author: Sam#The script to add user #/etc/passwd infoecho "please input username:"read nameecho "please inpu number:"read numn=1while [ $n -le $num]do    /usr/sbin/useradd $name$n #循环添加用户    n=`expr $n + 1`done#/etc/shadow infoecho "please input the password:"read passwdm=1while [ $m -le $num ]do    echo $passwd | /usr/bin/passwd --stdin $name$m    m=`expr $m +1`done#-----------------------------------------------------------cat deluser.sh#!/bin/shecho "please input username:"read nameecho "please input number:"read numsum=0while [ $sum -lt $num ]do    sum=`expr $sum+1`    /usr/sbin/userdel -r $name$sum #批量删除用户done#-----------------------------------------------------------#! /bin/shnum=1while [ $num -le 10 ]do    SUM=`expr $num \* $num`    echo $SUM    num=`expr $num + 1`doneuntil语句,格式:#-----------------------------------------------------------until 条件do命令doneuntil类似while循环,不同的是until是条件返回值为假时才继续执行。cat until#!/bin/shuntil [ -x /etc/inittab ]do    /bin/ls -l /etc/inittab    exit 0donecat read.until#-----------------------------------------------------------#!/bin/bash#"read" "until" usageecho "Press Y/y to stop..."read inputuntil [ "$input" = "Y" ] || [ "$input" = "y" ]do    echo "error input,please try again..."    read inputdone    echo "Stop here!"跳出循环:breakcontinue#-----------------------------------------------------------break:跳出整个循环continue:跳过本次循环,进行下次循环shift指令:参数左移,每执行一次,参数序列顺#-----------------------------------------------------------次左移一个位置,$#的值减1,用于分别处理每个参数,移出去的参数不再可用cat shift#!/bin/shif [ $# -le 0 ]then    echo "Not enough parameters"    exit 0fisum=0while [ $# -gt 0 ]do    su=`expr $sum + $1`    shiftdone    echo $sum函数应用函数的定义:#-----------------------------------------------------------函数名(){    命令序列}函数的调用:不带()函数名参数1 参数2 …函数中的变量:#-----------------------------------------------------------变量均为全局变量,没有局部变量函数中的参数:调用函数时,可以传递参数,在函数中用$1$2…来引用cat functionHELP(){    echo "Usage: sh function \$1 \$2 \$3"}if [ $# -ne 3 ]then    HELPelse    echo "thank for your input, the three arguments is 1 2 3. "fiShell 脚本调试#-----------------------------------------------------------sh -x script    这将执行该脚本并显示所有变量的值。sh -n script    不执行脚本只是检查语法的模式,将返回所有语法错误。sh 脚本1、对脚本有r权限2、对脚本所在目录有rx权限脚本1、对脚本有rx权限2、对脚本所在目录有rx权限
0 0
原创粉丝点击