`
天梯梦
  • 浏览: 13625153 次
  • 性别: Icon_minigender_2
  • 来自: 洛杉矶
社区版块
存档分类
最新评论

Linux Shell高级技巧(一)

 
阅读更多

该系列将重点介绍Linux Shell中的高级使用技巧,其主要面向有一定经验的Shell开发者、Linux系统管理员,以及Linux的爱好者。博客中的示例主要来源于网络和一 些经典书籍,在经过本人的收集和整理之后,以系列博客的形式呈现给诸位。如果大家有更多更好的Shell脚本经典示例,且愿意在这里与我们一同分享的话, 可以以邮件、博客回复等形式与我联系,我将会尽量保证该系列的持续更新。

一、将输入信息转换为大写字符后再进行条件判断:

      我们在读取用户的正常输入后,很有可能会将这些输入信息用于条件判断,那么在进行比较时,我们将不得不考虑这些信息的大小写匹配问题。

      /> cat > test1.sh

      #!/bin/sh
      echo -n "Please let me know your name. "
      read name
      #将变量name的值通过管道输出到tr命令,再由tr命令进行大小写转换后重新赋值给name变量。
      name=`echo $name | tr [a-z] [A-Z]`
      if [[ $name == "STEPHEN" ]]; then
          echo "Hello, Stephen."
      else
          echo "You are not Stephen."
      fi
      CTRL+D
      /> ./test1.sh
      Please let me know your name. stephen
      Hello, Stephen.

二、为调试信息设置输出级别:
    
      我们经常在调试脚本时添加一些必要的调试信息,以便跟踪到程序中的错误。在完成调试后,一般都会选择删除这些额外的调试信息,在过了一段时间之后,如果脚 本需要添加新的功能,那么我们将不得不重新进行调试,这样又有可能需要添加这些调试信息,在调试成功之后,这些信息可能会被再次删除。如果我们能够为我们 的调试信息添加调试级别,使其只在必要的时候输出,我想这将会是一件非常惬意的事情。
      /> cat > test2.sh
      #!/bin/sh
      if [[ $# == 0 ]]; then
          echo "Usage: ./test2.sh -d debug_level"
          exit 1
      fi
      #1. 读取脚本的命令行选项参数,并将选项赋值给变量argument。
      while getopts d: argument
      do
          #2. 只有到选项为d(-d)时有效,同时将-d后面的参数($OPTARG)赋值给变量debug,表示当前脚本的调试级别。
          case $argument in
          d) debug_level=$OPTARG ;;
          \?) echo "Usage: ./test2.sh -d debug_level"
              exit 1
              ;;
          esac
      done
      #3. 如果debug此时的值为空或者不是0-9之间的数字,给debug变量赋缺省值0.
      if [[ -z $debug_level ||  $debug_level != [0-9] ]]; then
          debug_level=0
      fi
      echo "The current debug_level level is $debug_level."
      echo -n "Tell me your name."
      read name
      name=`echo $name | tr [a-z] [A-Z]`
      if [ $name = "STEPHEN" ];then
          #4. 根据当前脚本的调试级别判断是否输出其后的调试信息,此时当debug_level > 0时输出该调试信息。
          test $debug_level -gt 0 && echo "This is stephen."
          #do something you want here.
      elif [ $name = "ANN" ]; then
          #5. 当debug_level > 1时输出该调试信息。
          test $debug_level -gt 1 && echo "This is ann."
          #do something you want here.
      else
          #6. 当debug_level > 2时输出该调试信息。
          test $debug_level -gt 2 && echo "This is others."
          #do any other else.
      fi
      CTRL+D
      /> ./test2.sh
      Usage: ./test2.sh -d debug_level
      /> ./test2.sh -d 1
      The current debug level is 1.
      Tell me your name. ann
      /> ./test2.sh -d 2
      The current debug level is 2.
      Tell me your name. ann
      This is ann.

三、判断参数是否为数字:

      有些时候我们需要验证脚本的参数或某些变量的值是否为数字,如果不是则需要需要给出提示,并退出脚本。
      /> cat > test3.sh
      #!/bin/sh
      #1. $1是脚本的第一个参数,这里作为awk命令的第一个参数传入给awk命令。
      #2. 由于没有输入文件作为输入流,因此这里只是在BEGIN块中完成。
      #3. 在awk中ARGV数组表示awk命令的参数数组,ARGV[0]表示命令本身,ARGV[1]表示第一个参数。
      #4. match是awk的内置函数,返回值为匹配的正则表达式在字符串中(ARGV[1])的起始位置,没有找到返回0。
      #5. 正则表达式的写法已经保证了匹配的字符串一定是十进制的正整数,如需要浮点数或负数,仅需修改正则即可。
      #6. awk执行完成后将结果返回给isdigit变量,并作为其初始化值。
      #7. isdigit=`echo $1 | awk '{ if (match($1, "^[0-9]+$") != 0) print "true"; else print "false" }' `
      #8. 上面的写法也能实现该功能,但是由于有多个进程参与,因此效率低于下面的写法。
      isdigit=`awk 'BEGIN { if (match(ARGV[1],"^[0-9]+$") != 0) print "true"; else print "false" }' $1`
      if [[ $isdigit == "true" ]]; then
          echo "This is numeric variable."
          number=$1
      else
          echo "This is not numeric variable."
          number=0
      fi
      CTRL+D
      /> ./test3.sh 12

      This is numeric variable.
      /> ./test3.sh 12r
      This is not numeric variable.

四、判断整数变量的奇偶性:

      为了简化问题和突出重点,这里我们假设脚本的输入参数一定为合法的整数类型,因而在脚本内部将不再进行参数的合法性判断。
      /> cat > test4.sh
      #!/bin/sh
      #1. 这里的重点主要是sed命令中正则表达式的写法,它将原有的数字拆分为两个模式(用圆括号拆分),一个前面的所有高位数字,另一个是最后一位低位数字,之 后再用替换符的方式(\2),将原有数字替换为只有最后一位的数字,最后将结果返回为last_digit变量。
      last_digit=`echo $1 | sed 's/\(.*\)\(.\)$/\2/'`
      #2. 如果last_digit的值为0,2,4,6,8,就表示其为偶数,否则为奇数。
      case $last_digit in
      0|2|4|6|8)
          echo "This is an even number." ;;
      *)
          echo "This is not an even number." ;;
      esac
      CTRL+D
      /> ./test4.sh 34
      This is an even number.
      /> ./test4.sh 345
      This is not an even number.
       
五、将Shell命令赋值给指定变量,以保证脚本的移植性:

      有的时候当我们在脚本中执行某个命令时,由于操作系统的不同,可能会导致命令所在路径的不同,甚至是命令名称或选项的不同,为了保证脚本具有更好的平台移 植性,我们可以将该功能的命令赋值给指定的变量,之后再使用该命令时,直接使用该变量即可。这样在今后增加更多OS时,我们只需为该变量基于新系统赋予不 同的值即可,否则我们将不得不修改更多的地方,这样很容易导致因误修改而引发的Bug。
      /> cat > test5.sh
      #!/bin/sh
      #1. 通过uname命令获取当前的系统名称,之后再根据OS名称的不同,给PING变量赋值不同的ping命令的全称。
      osname=`uname -s`
      #2. 可以在case的条件中添加更多的操作系统名称。
      case $osname in
      "Linux")
          PING=/usr/sbin/ping ;;
      "FreeBSD")
          PING=/sbin/ping ;;
      "SunOS")
          PING=/usr/sbin/ping ;;
      *)
          ;;
      esac
      CTRL+D
      /> . ./test5.sh
      /> echo $PING
      /usr/sbin/ping
   
六、获取当前时间距纪元时间(1970年1月1日)所经过的天数:

      在获取两个时间之间的差值时,需要考虑很多问题,如闰年、月份中不同的天数等。然而如果我们能够确定两个时间点之间天数的差值,那么再计算时分秒的差值时 就非常简单了。在系统提供的C语言函数中,获取的时间值是从1970年1月1日0点到当前时间所流经的秒数,如果我们基于此计算两个时间之间天数的差值, 将会大大简化我们的计算公式。
      /> cat > test6.sh
      #!/bin/sh
      #1. 将date命令的执行结果(秒 分 小时 日 月 年)赋值给数组变量DATE。
      declare -a DATE=(`date +"%S %M %k %d %m %Y"`)
      #2. 为了提高效率,这个直接给出1970年1月1日到新纪元所流经的天数常量。
      epoch_days=719591
      #3. 从数组中提取各个时间部分值。
      year=${DATE[5]}
      month=${DATE[4]}
      day=${DATE[3]}
      hour=${DATE[2]}
      minute=${DATE[1]}
      second=${DATE[0]}
      #4. 当月份值为1或2的时候,将月份变量的值加一,否则将月份值加13,年变量的值减一,这样做主要是因为后面的公式中取月平均天数时的需要。
      if [ $month -gt 2 ]; then
          month=$((month+1))
      else
          month=$((month+13))
          year=$((year-1))
      fi
      #5. year变量参与的运算是需要考虑闰年问题的,该问题可以自行去google。
      #6. month变量参与的运算主要是考虑月平均天数。
      #7. 计算结果为当前日期距新世纪所流经的天数。
      today_days=$(((year*365)+(year/4)-(year/100)+(year/400)+(month*306001/10000)+day))
      #8. 总天数减去纪元距离新世纪的天数即可得出我们需要的天数了。
      days_since_epoch=$((today_days-epoch_days))
      echo $days_since_epoch
      seconds_since_epoch=$(((days_since_epoch*86400)+(hour*3600)+(minute*60)+second))
      echo $seconds_since_epoch
      CTRL+D
      /> . ./test6.sh
      15310
      1322829080
      需要说明的是,推荐将该脚本的内容放到一个函数中,以便于我们今后计算类似的时间数据时使用。 

 

原文:Linux Shell高级技巧(一)

 

分享到:
评论

相关推荐

    Linux Shell高级技巧实战总结

    Linux Shell高级技巧实战总结 一、将输入信息转换为大写字符后再进行条件判断 二、为调试信息设置输出级别 三、判断参数是否为数字 四、判断整数变量的奇偶性 五、将Shell命令赋值给指定变量,以保证脚本的移植性 六...

    Linux Shell编程3/3

    Linux Shell编程经典著作: 第一部分SHELL |_文件安全与权限 |_使用find和xargs |_后台执行命令 |_文件名置换 |_shell输入与输出 |_命令执行顺序 第二部分文本过滤 |_正则表达式介绍 ...

    高级shell编程 第五部分 高级shell编程技巧(共5部分)

    第五部分 高级shell编程技巧 第25章 深入讨论 第26章 shell 工 具 第27章 几个脚本例子 第28章 运行级别脚本 第29章 cgi 脚 本 附录 常用shell命令

    Shell高级编程(中文版)

    Shell高级编程(中文版) 毫无疑问,UNIX/Linux 最重要的软件之一就是 shell,目前最流行的 shell 被称为 Bash(Bourne Again Shell), 几乎所有的 Linux 和绝大部分的 UNIX 都可以使用 Bash。作为系统与用户之间的交互...

    LINUX与UNIX SHELL编程指南

    网上此书的目录很乱,而且一本书分割为好多文件。我详细整理了目录,并且合并为...第五部分 高级SHELL编程技巧 第二五章 深入讨论 第二六章 SHELL工具 第二七章 几个脚本例子 第二八章 运行级别脚本 第二九章 CGI脚本

    实战Linux Shell编程与服务器管理-作者:卧龙小三(1)

     操作系统Shell编程一直是系统管理员必备高级技能之一。主机管理的上乘之道,就在于尽量让计算机去完成所有的琐事。要达到这个境界,管理者必须具备相当程度的Shell操控能力与Shell程序设计能力,笔者拥有丰富的...

    绝版经典 LINUX与UNIX SHELL编程指南 PDF 高清版 [16.3M]

    shell是一种完整的编程语言,易学易用;shell脚本可以使烦人的手工作业自动...第五部分 高级SHELL编程技巧 第二五章 深入讨论 第二六章 SHELL工具 第二七章 几个脚本例子 第二八章 运行级别脚本 第二九章 CGI脚本

    Linux Shell编程1/3

    Linux Shell编程经典著作: 第一部分SHELL |_文件安全与权限 |_使用find和xargs |_后台执行命令 |_文件名置换 |_shell输入与输出 |_命令执行顺序 第二部分文本过滤 |_正则表达式介绍 ...

    Linux Shell编程2/3

    Linux Shell编程经典著作: 第一部分SHELL |_文件安全与权限 |_使用find和xargs |_后台执行命令 |_文件名置换 |_shell输入与输出 |_命令执行顺序 第二部分文本过滤 |_正则表达式介绍 ...

    LINUX与UNIX SHELL编程指南(很全)

    第一部分 shell 第1章 文件安全与权限 1 1.1 文件 1 1.2 文件类型 2 1.3 权限 2 1.4 改变权限位 4 1.4.1 符号模式 4 1.4.2 chmod命令举例 5 1.4.3 绝对模式 5 1.4.4 chmod命令的其他例子 6 1.4.5 可以选择使用符号...

    Linux shell编程指南

    本书共分五部分,详细介绍了shell编程技巧,各种UNIX命令及语法,还涉及了UNIX下的文字处理以及少量的系统管理问题。本书内容全面、文字简洁流畅,适合Shell编程人员学习、参考。 目 录 译者序 前言 第一部分 ...

    Linux shell编程指南.rar

    本文档是Linux shell编程指南教程,适于Linux编程新手,高清pdf。共分为5部分,第一部分:shell,第二部分:分文本过滤,第三部分:登陆环境,第四部分:shell编程,第五部分:高级shell编程技巧。

    Linux与UNIX Shell编程指南.rar

    内容简介 本书共分五部分 ,详细介绍了SHELL编程技巧,各种UNIX命令及语法,还...第五部分 高级SHELL编程技巧 第二五章 深入讨论 第二六章 SHELL工具 第二七章 几个脚本例子 第二八章 运行级别脚本 第二九章 CGI脚本

    Linux Shell 编程 入门、提高、精通

    第一部分 shell 第1章文件安全与权限 第2章使用find和xargs ...第五部分高级shell编程技巧 第25章深入讨论 第26章shell 工具 第27章几个脚本例子 第28章运行级别脚本 第29章cgi 脚本 附录常用shell命令

    LINUX命令、编辑器与SHELL编程PDF.part01

     一本值得每一位Linux管理人员、开发人员和高级用户拥有的指南!  本书特点:  1.它是Pearson、Amazon、Bames&Noble 计算机畅销书!  2.知名Linux专家Mark Sobell 编写的这本书,为系统管理员、开发人员和高级...

    linux shell 编程教程

    linux shell编程 教程大全 目 录 译者序 前言 第一部分 shell 第1章 文件安全与权限 1 1.1 文件 1 1.2 文件类型 2 1.3 权限 2 1.4 改变权限位 4 1.4.1 符号模式 4 1.4.2 chmod命令举例 5 1.4.3 绝对模式 5 1.4.4 ...

    Linux与unix+shell编程指南.pdf

    非常基础的shell编程文档主要分了五个部分 1.shell 2.文本过滤 3.登录环境 4.基础shell编程 5.高级shell编程技巧

    Linux与unix shell编程指南

    本书共分五部分,详细介绍了shell编程技巧,各种UNIX命令及语法,还涉及了UNIX下的文字处理以及少量的系统管理问题。本书内容全面、文字简洁流畅,适合Shell编程人员学习、参考。 目 录 译者序 前言 第一部分 shell ...

    LINUX命令、编辑器与SHELL编程PDF.part02.rar

     一本值得每一位Linux管理人员、开发人员和高级用户拥有的指南!  本书特点:  1.它是Pearson、Amazon、Bames&Noble 计算机畅销书!  2.知名Linux专家Mark Sobell 编写的这本书,为系统管理员、开发人员和高级...

Global site tag (gtag.js) - Google Analytics