zoukankan      html  css  js  c++  java
  • 编写shell脚本

    shell有两种执行命令的方式:

    交互式(Interactive):解释执行用户的命令,用户输入一条命令,Shell就解释执行一条。

    批处理(Batch):用户事先写一个Shell脚本(Script),其中有很多条命令,让Shell一次把这些命令执行完,而不必一条一条地敲命令。

    我们要知道bash和sh不是一个东西,我们需要了解,bash完全兼容sh,也就是说,用sh写的脚本可以不加修改的在bash中执行。


     linux环境下可以用vim编辑器写shell脚本。下面先展示下脚本

    #!/bin/sh
    a="hello world!"
    num=2
    echo "a is : $a num is : ${num}nd"
    运行结果: a is : hello world! num is : 2nd

    tips: # !/bin/sh 是固定格式,用于声明使用的什么脚本。

    1.变量概念

    好了,第一个小程序运行成功了,接下来看看变量定义:

    例子:varibleName="value"

    首先有一点,变量名和等号之间不能有空格,这点千万注意,因为我们平时写其他程序的时候可能已经养成了这种习惯,在shell这里需要注意这个习惯,

    然后要知道的一些变量命名规则:

    1,首个字符必须为字母(a-z,A-Z)。

    2,中间不能有空格,可以使用下划线(_)。

    3,不能使用标点符号。

    4,不能使用bash里的关键字(可用help命令查看保留关键字)。

    定义好变量我们就要开始使用变量了,如何使用变量,需要在自己定义的变量名上加上大括号,然后最前面写上$字符,例如

    who="dog"

    echo who is ${who}?

    其实变量可以直接用$who取,但是为了养成好习惯,还是加上括号吧。

    接着我们对shell的变量类型做个了解,有三种变量:

    1 局部变量

    局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。

    2 环境变量

    所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。

    3 shell变量

    shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行

    shell中一些比较特殊的变量:

    特殊变量 含义
    $0 当前脚本的文件名
    $n 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。
    $# 传递给脚本或函数的参数个数。
    $* 传递给脚本或函数的所有参数。
    $@ 传递给脚本或函数的所有参数。被双引号(" ")包含时,与 $* 稍有不同,下面将会讲到。
    $? 上个命令的退出状态,或函数的返回值。
    $$ 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。
     

    2.算数运算

    Bash 支持很多运算符,包括算数运算符、关系运算符、布尔运算符、字符串运算符和文件测试运算符。
    原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。
    expr 是一款表达式计算工具,使用它能完成表达式的求值操作。

    接着写一小段shell,按照下图:

    1. # /bin/bash  
    2. value=`expr 2 + 2`  
    3. echo "Total value :${value}"  
    图中有几个点要注意,第一行是linux的注释,以#号开头。

    在第二行中注意赋值地方是没有空格的,而在计算表达式的时候之间是有空格的。 expr 2 + 2表达式被 ` 号括起来。注意 · 号并不是单引号,而是键盘上Esc下面的符号。(半角英文模式)

    运行结果

    Lee@Lee-PC /Desktop
    $ sh test.sh
    Total value :4

    好了接着跟我一起输入如下内容:

    1. # /bin/bash  
    2. a=10  
    3. b=20  
    4.   
    5. value=`expr 2 + 2`  
    6. echo "Total value :${value}"  
    7.   
    8. value=`expr $a * $b`  
    9. echo "a * b : ${value}"  
    10.   
    11. value=`expr $b % $a`  
    12. echo "a % b : ${value}"  
    13.   
    14. if [ $a == $b ]  
    15. then  
    16.     echo "a equals b"  
    17. fi  
    18.   
    19. if [ $a != $b ]  
    20. then  
    21.     echo "a not equals b"  
    22. fi  

    一起看看运行结果是不是相同。

    $ sh test.sh
    Total value :4
    a * b : 200
    a % b : 0
    a not equals b

    对上面稍做说明:

    在计算a * b的时候,我们的表示有用到转义字符 (反斜杠) 

    条件表达式要放在方括号之间,并且要有空格,例如 [$a==$b] 是错误的,必须写成 [ $a == $b ]

    if...then...fi 是条件语句,后面我们会对其再进行了解

    3.关系运算

    if语句shell格式为:

    if [ $a=$b ]then

    //do something

    elseif [ $a=$b ]then

    //do

    else

    //do

    fi  #结尾

    接着上面的脚本,我们继续编辑输入:

    1. if [ $a -eq $b ]  
    2. then  
    3.     echo "$a -eq $b"  
    4. else  
    5.     echo "a not equals b "  
    6. fi  
    7.   
    8. if [ $a -gt $b ]  
    9. then  
    10.     echo "$a gt $b"  
    11. else  
    12.     echo "a not greater than b"  
    13. fi  
    14.   
    15. if [ $a -le $b ]  
    16. then  
    17.     echo "$a le $b"  
    18. else  
    19.     echo "a not less or equal to b"  
    20. fi  

    运行结果:(有前面编辑输入过的内容哈)

    $ sh test.sh
    Total value :4
    a * b : 200
    a % b : 0
    a not equals b
    a not equals b
    a not greater than b
    10 le 20

    好了,写脚本的时候就能猜出来-gt 和-le的作用吧。我们系统的来看看

    关系运算符列表

    运算符 说明 举例
    -eq 检测两个数是否相等,相等返回 true。 [ $a -eq $b ] 返回 true。
    -ne 检测两个数是否相等,不相等返回 true。 [ $a -ne $b ] 返回 true。
    -gt 检测左边的数是否大于右边的,如果是,则返回 true。 [ $a -gt $b ] 返回 false。
    -lt 检测左边的数是否小于右边的,如果是,则返回 true。 [ $a -lt $b ] 返回 true。
    -ge 检测左边的数是否大等于右边的,如果是,则返回 true。 [ $a -ge $b ] 返回 false。
    -le 检测左边的数是否小于等于右边的,如果是,则返回 true [ $a -le $b ] 返回 true。

    这次我们的shell脚本学习就到这里,后面还有一些内容一些运算符,还有字符串等等东西。
    4.循环
    for
    实例1.1 最基本的for循环: (传统的形式,for var in …)
    代码示例
    #!/bin/bash
    for x in one two three four
    do
            echo number $x
    done
    注:”for” 循环总是接收 “in” 语句之后的某种类型的字列表。在本例中,指定了四个英语单词,但是字列表也可以引用磁盘上的文件,甚至文件通配符。
    实例1.2 对目录中的文件做for循环
    代码如下:

    #!/bin/bash
    for x in /var/log/*
    do
            #echo "$x is a file living in /var/log"
            echo $(basename $x) is a file living in /var/log
    done
    注:这个$x获得的是绝对路径文件名;可以使用 “basename” 可执行程序来除去前面的路径信息。如果只引用当前工作目录中的文件(例如,如果输入 “for x in *”),则产生的文件列表将没有路径信息的前缀。
    实例1.3 对位置参数做for循环
    代码如下:

    #!/bin/bash
    for thing in "$@"
    do
            echo you typed ${thing}.
    done

    实例1.4 for循环中用seq产生循环次数,加上C语言形式的for循环语句
    代码如下:

    #!/bin/bash
    echo "for: Traditional form: for var in ..."
    for j in $(seq 1 5)
    do
            echo $j
    done

    echo "for: C language form: for (( exp1; exp2; exp3 ))"

    for (( i=1; i<=5; i++ ))
    do
            echo "i=$i"
    done

    注:对于固定次数的循环,可以通过seq命令来实现,就不需要变量的自增了;这里的C语言for循环风格是挺熟悉的吧。
    while
    实例2.1 循环输出1到10的数字
    代码如下:

    #!/bin/bash
    myvar=1
    while [ $myvar -le 10 ]
    do
            echo $myvar
            myvar=$(( $myvar + 1 ))
    done

    注:只要特定条件为真,”while” 语句就会执行

    Linux Shell中写循环时,常常要用到变量的自增,现在总结一下整型变量自增的方法。
    我所知道的,bash中,变量自增,目前有五种方法:
    1. i=`expr $i + 1`;
    2. let i+=1;
    3. ((i++));
    4. i=$[$i+1];
    5. i=$(( $i + 1 ))
    可以实践一下,简单的实例如下:
    代码如下:

    #!/bin/bash
    i=0;
    while [ $i -lt 4 ];
    do
          echo $i;
          i=`expr $i + 1`;
          # let i+=1;
          # ((i++));
          # i=$[$i+1];
          # i=$(( $i + 1 ))
    done
     
    在shell下使function.sh脚本获取可执行权限并执行脚本:

    chomd +x function.sh

    脚本编写完毕后一般需要立即执行或加入linux计划任务中,

    ./function.sh 立即执行

    sh function.sh 立即执行

     计划任务crontab的域
    为了能够在特定的时间运行作业,需要了解c r o n t a b文件每个条目中各个域的意义和格式。

    下面是c r o n t a b的格式:
    分 时 日 月 星期 要运行的命令


    下面就是这些域:
    第1列分钟1~5 9
    第2列小时1~2 3(0表示子夜)
    第3列日1~3 1
    第4列月1~1 2
    第5列星期0~6(0表示星期天)
    第6列要运行的命令
      
    C r o n t a b文件的一个条目是从左边读起的,第一列是分,最后一列是要运行的命令,它位
    于星期的后面。
    在这些域中,可以用横杠-来表示一个时间范围,例如你希望星期一至星期五运行某个作
    业,那么可以在星期域使用1 - 5来表示。还可以在这些域中使用逗号“,”,例如你希望星期一
    和星期四运行某个作业,只需要使用1 , 4来表示。可以用星号*来表示连续的时间段。如果你
    对某个表示时间的域没有特别的限定,也应该在该域填入*。该文件的每一个条目必须含有5
    个时间域,而且每个域之间要用空格分隔。该文件中所有的注释行要在行首用#来表示。
      
    crontab条目举例
    这里有c r o n t a b文件条目的一些例子:
    30 21* * * /apps/bin/cleanup.sh
    上面的例子表示每晚的2 1 : 3 0运行/ a p p s / b i n目录下的c l e a n u p . s h。
    45 4 1,10,22 * * /apps/bin/backup.sh
    上面的例子表示每月1、1 0、2 2日的4 : 4 5运行/ a p p s / b i n目录下的b a c k u p . s h。
    10 1 * * 6,0 /bin/find -name "core" -exec rm {} ;
    上面的例子表示每周六、周日的1 : 1 0运行一个f i n d命令。
    0,30 18-23 * * * /apps/bin/dbcheck.sh
    上面的例子表示在每天1 8 : 0 0至2 3 : 0 0之间每隔3 0分钟运行/ a p p s / b i n目录下的d b c h e c k . s h。
    0 23 * * 6 /apps/bin/qtrend.sh
    上面的例子表示每星期六的11 : 0 0 p m运行/ a p p s / b i n目录下的q t r e n d . s h。
      
    你可能已经注意到上面的例子中,每个命令都给出了绝对路径。当使用c r o n t a b运行s h e l l
    脚本时,要由用户来给出脚本的绝对路径,设置相应的环境变量。记住,既然是用户向c r o n
    提交了这些作业,就要向c r o n提供所需的全部环境。不要假定c r o n知道所需要的特殊环境,它
    其实并不知道。所以你要保证在s h e l l脚本中提供所有必要的路径和环境变量,除了一些自动
    设置的全局变量。
      
    命令形式:
    c r o n t a b命令的一般形式为:
    Crontab [-u user] -e -l -r
    其中:
    -u 用户名。
    -e 编辑c r o n t a b文件。
    -l 列出c r o n t a b文件中的内容。
    -r 删除c r o n t a b文件。
    如果使用自己的名字登录,就不用使用- u选项,因为在执行c r o n t a b命令时,该命令能够
    知道当前的用户
      
    建一个新的crontab文件
      
    在考虑向c r o n进程提交一个c r o n t a b文件之前,首先要做的一件事情就是设置环境变量
    E D I TO R。c r o n进程根据它来确定使用哪个编辑器编辑c r o n t a b文件。9 9 %的U N I X和L I N U X用
    户都使用v i,如果你也是这样,那么你就编辑$ H O M E目录下的. p r o f i l e文件,在其中加入这样
    一行:
    EDITOR=vi; export EDITOR
    然后保存并退出。
    不妨创建一个名为< u s e r > c r o n的文件,其中< u s e r >是用户名,例如, j a m e s c r o n。在该文件中加入如下的内容。
    #。。。。这里是解释的话
    0,15,30,45 18-06 * * * /bin/echo 'time'>/dev/console
      
    保存并退出。确信前面5个域用空格分隔。
    在上面的例子中,系统将每隔1 5分钟向控制台输出一次当前时间。如果系统崩溃或挂起,
    从最后所显示的时间就可以一眼看出系统是什么时间停止工作的。在有些系统中,用t t y 1来表
    示控制台,可以根据实际情况对上面的例子进行相应的修改。
    为了提交你刚刚创建的c r o n t a b文件,可以把这个新创建的文件作为c r o n命令的参数:
    $ crontab jamescron
    现在该文件已经提交给c r o n进程,它将每隔1 5分钟运行一次。
    同时,新创建文件的一个副本已经被放在/ v a r / s p o o l / c r o n目录中,文件名就是用户名(即,
    james)。
      
    列出crontab文件:
      
    为了列出c r o n t a b文件,可以用:
    你将会看到和上面类似的内容。可以使用这种方法在$ H O M E目录中对c r o n t a b文件做一备
    份:
    $ crontab -l > $HOME/mycron
    这样,一旦不小心误删了c r o n t a b文件,可以用上一节所讲述的方法迅速恢复。
      
    编辑crontab文件:
      
    如果希望添加、删除或编辑c r o n t a b文件中的条目,而E D I TO R环境变量又设置为v i,那么
    就可以用v i来编辑c r o n t a b文件,相应的命令为:
    $ crontab -e
    可以像使用v i编辑其他任何文件那样修改c r o n t a b文件并退出。如果修改了某些条目或添加了新的条目,那么在保存该文件时, c r o n会对其进行必要的完整性检查。如果其中的某个域出现了超出允许范围的值,它会提示你。
    保存并退出。最好在c r o n t a b文件的每一个条目之上加入一条注释,这样就可以知道
    它的功能、运行时间,更为重要的是,知道这是哪位用户的作业。
    可以使用前面讲过的crontab -l命令列出它的全部信息
      
    为了删除c r o n t a b文件,可以用:
    $ crontab -r


    注:本文由王智磊(王大宝儿)整理编写,也参考借鉴了很多大神的笔记,分享代码,分享成功,欢迎各位交流和转载,转载请注明出处(博客园:王大宝儿)http://www.cnblogs.com/wangzhilei/

  • 相关阅读:
    Linux crontab 的常用定时方式
    Windows 查看端口及进程信息
    java.io.IOException: com.esotericsoftware.kryo.KryoException
    Linux 如何让挂载的硬盘永久生效
    六边形架构-微服务基石
    包和工具
    谈一谈对java简单的理解
    HTTP报文 「HTTP
    四层 or 七层 「HTTP
    setTimeout不生效
  • 原文地址:https://www.cnblogs.com/wangzhilei/p/6930709.html
Copyright © 2011-2022 走看看