美文网首页
Linux Shell 教程 快速上手

Linux Shell 教程 快速上手

作者: 天高s | 来源:发表于2017-02-23 09:39 被阅读0次

    作为一个 Java 程序员,Go 爱好者,自然免不了天天和 Linux 打交道,也曾经写过一点点 shell 脚本,但是对那个反人类的语法深感厌恶,空格不对都不行。无奈项目需要一定要用 shell 来实现一个工具,学习的过程总是不那么顺风的,不过搞完之后也觉得没那么讨厌了。整理一下几天所得,希望能让一个从没写过 shell 但是还挺熟悉 Linux 的可以立马完成一个可用的脚本。

    1. 执行顺序

    脚本顺序执行,原来怎么敲命令的就怎么写

    1. 变量赋值

      # 变量赋值时等号两边不能有空格
      # 单引号是固定字符串
      pa='string'
      
      # 双引号可包含变量
      pb="ps is ${pa}"
      
      # 接受命令返回
      pc=`ls -alh`
      
    2. 数组及其遍历

      arr=(aa bb cc dd ff)
      # 通过下标访问
      for ((i=0; i<5; i++))
      do
          echo "$i: ${arr[$i]}"
      done
      
      # 遍历访问
      for s in ${arr[@]}
      do
      echo "  $s"
      done
      
      # 空格分隔的字符串也能遍历,但是不能像上面的方式一样用下标访问元素
      arr2='a1 a2 a3 a4 a5'
      for s in ${arr2}
      do
      echo ${s}
      done
      
    3. 条件判断

      # shell 脚本都是指令,if 的语句一定要注意空格
      # 第一种写法,下面输出 ok
      if [[ 10 -gt 3 ]]; then echo ok; else echo no; fi
      
      # 第二种, ** 注意(): 下面输出 ok
      if [ 2 > 3 ]; then 
          echo ok
      fi
      
      # 第三种, 下面输出 no
      if [[ 2 > 3 ]]
      then 
          echo ok
      else 
          echo no
      fi
      
    4. 定义函数

      res=0
      echo $res
      
      add() {
          ((res = $1 + $2))
      }
      add 12 13
      echo $res
      
    5. $? 说明

      # $?接受的是上一条命令执行后的返回值
      ls /home
      
      # 下面的输出是 0
      echo $?
      
      testReurn() {
          return 8
      }
      testReurn
      
      # 下面的输出是 8 
      echo $?
      
    6. 字符串操作

      a='stringA'
      b='stringB'
      
      # 判断是否相等,下面输出 no
      if [[ $a == $b ]]; then echo yes; else echo no; fi
      
      # 字符串拼接, 下面输出 yes
      if [[ 'stringAstringB' == "${a}${b}" ]]; then echo yes; fi
      
      # 取字符串长度, 下面输出 7
      echo ${#a}
      
      # 截取字符串, 下面输出  string, ing
      echo "${a:0:6}, ${a:3:3}"
      
      # 判断两个字符串是否有相同前缀, 下面输出 yes
      if [[ ${a:0:5} == ${b:0:5} ]]; then echo yes; else echo no; fi
      
      # 字符串切分为数组, IFS 变量指定分隔符, 分隔符前后空格会被略去
      IFS=, read -r -a arr <<< 'a,b  ,c, d,g e,   ss'
      for str in ${arr[@]}; do echo "'${str}'"; done
      
    7. 文件和目录判断

      if [[ -f $filename ]]; then
        echo "$filename 是一个文件"
      elif [[ -d $filename ]]; then
        echo "$filename 是一个目录"
      elif [[ -p $filename ]]; then
        echo "$filename 是一个管道文件"
      elif [[ -S $filename ]]; then
        echo "$filename 是一个 sokcet 文件"
      elif [[ -b $filename ]]; then
        echo "$filename 是 block device"
      elif [[ -c $filename ]]; then
        echo "$filename 是 character device"
      fi
      if [[ -L $filename ]]; then
        echo "$filename 是一个软链接"
      fi
      # 对于软链接,使用-L测试时,当链接指向的目标文件不存在时会返回false
      if [[ -L $filename || -e $filename ]]; then
        echo "$filename 存在 (可能是失效的链接)"
      fi
       
      if [[ -L $filename && ! -e $filename ]]; then
        echo "$filename 是失效的软链接"
      fi
      
    8. 内容既输出到控制台也输出到文件里

      
      echo 'ok'| tee -a bb.log
      
    9. 处理退出信号

      trap "rm -f ${lock_file}; echo 'exited ok.'" SIGINT SIGQUIT
      
      # SIGHUP:从终端终止或退出正在前台运行的进程
      # SIGINT:从键盘按下 Ctrl-C
      # SIGQUIT:从键盘按下 Ctrl-\
      # SIGTERM :软件终止信号
      
    10. 处理参数

      if [[ "$OSTYPE" == "darwin"* ]]; then
          # Mac OSX ( brew install gnu-getopt )
          getopt_cmd="$(brew --prefix gnu-getopt)/bin/getopt"
      else
          # linux-gnu
          getopt_cmd="getopt"
      fi
      long_opts="once,name:,note:"
      
      opts=$($getopt_cmd -n $0 -o - --long $long_opts -- "$@")
      
      eval set -- "$opts"
      
      while : 
      do
          case "$1" in
          --once)
              once="true" ; shift 1 ;;
          --name)
              name=$2  ; shift 2 ;;
              --note)
                  note=$2  ; shift 2 ;;
          --)
              shift ; break ;;
          *)
          echo "参数错误" ; exit 1 ;;
      esac
      done
      echo "once: ${once:-no}, name: ${name}, note: ${note}"
      
    11. MySQL 查询

      std_log='/var/log/test.log'
      err_log='/var/log/test.err.log'
      
      user='root'
      pwd=''
      host='127.0.0.1'
      db='mysql'
      
      exec_sql() {
          echo "exec_sql: $1" | tee -a ${std_log}
          mysql -u${user} -p${pwd} -h${host} -D${db} -s -N -e "$1" | tee -a ${std_log}
      }
      exec_sql "show databases"
      
    12. 标准输入输出重定向

    shell中,每个进程都和三个系统文
    件相关联:标准输入stdin,标准输出stdout和标准错误stderr,三个系统文件的文件描述符分别为0, 1, 2
    在使用 mysql 命令获取结果时会有一些警告信息
    mysql: [Warning] Using a password on the command line interface can be insecure.
    但是我要得到命令的结果不需要这些警告, 这个时候就需要重定向错误输出到其他地方
    num=`mysql -u${user} -p${pwd} -h${host} -D${db} -s -N -e "${count_sql}" 2>${err_log}

    注意

    此为个人这一周以来的小总结,并非专业的 shell 教程,旨在能帮助懂编程的人不会 shell 的能快速上手,少走一些我趟过的坑,减少一些搜索。
    有些原理我也不是太清楚,以后需要的时候才会去系统学习吧,现在这些已经能完成任务了。

    相关文章

      网友评论

          本文标题:Linux Shell 教程 快速上手

          本文链接:https://www.haomeiwen.com/subject/wibvwttx.html