• Shell编程(脚本)的经常使用命令和语句


    一些经常使用的Shell编程(脚本)命令和语句,能够满足一般需求。

    接收到的命令參数:
    • 參数个数:
    $#

    • 參数值:
    命令本身:$0
    第一个參数:$1
    第二个參数:$2
    ……

    退出命令:
    exit

    echo命令:
    • 换行:
    echo
    • 输出后不换行:
    echo -n "请选择(y/n)?"
    • 输出后不换行,并把光标移到最左(以便下次输出覆盖当前行)
    echo -ne "$i "

    • 利用转义符号输出双引號: 
    echo "欢迎使用"正式server"部署工具。"

    • 输出中带变量:
    echo "即将部署项目:$project_name"

    • 输出带转义符的字符串:
    echo -e "first second"

    • 输出到文件
    追加到文件尾:echo -e $log_info >> deploy.log
    覆盖文件内容:echo -e $log_info > deploy.log

    printf命令:
    (能够取代echo。格式化输出。和C语言中的printf函数功能同样)

    • 输出一个小数点后两位的数,并换行:
    printf "The number is %.2f. " 100

    • 输出一个指定宽度的字符串:
    左对齐:printf "%-20s %-15s %10.2f " "Stephen" "Liu" 35
    右对齐:printf "|%10s| " hello

    变量:
    • 定义: 
    profile="production"

    • 使用: 
    echo $profile

    • 变量拼接:
    log_info="$log_info,$target_ip"

    数组:
    • 定义:
    servers=("192.168.0.31" "192.168.0.39")
    projects=("public" "industry" "logistics" "misc")

    • 获得整个数组:
    ${projects[*]}

    • 获得数组元素个数:
    ${#servers[@]}

    数学运算:
    • 加:x=$(expr "$a" + "$b")
    • 减:x=$(($a - $b))
    • 乘:x=$(expr $a * $b)
    • 除:x= $(expr $a / $b)

    if 语句(条件推断相同适用于while语句和for语句):
    • 推断一个变量(project)是否非空:
    if [ $project ];then
      echo "Variable "project" is null."
    fi

    • 推断不等于:
    if [ $# -ne 3 ];then
      echo "命令行參数不是3个"
    fi

    注:数值大小推断的一些命令:
    gt:大于(greater than)
    lt:小于(less than)
    eq:等于(equal)
    ne:不等于(not equal)
    ge:大于等于(greater or equal)
    le:小于等于 (less or equal)

    • 布尔值推断:
        if [ "$is_ip_correct" = false ];then 
          echo "无效的ip地址,请使用以下ip之中的一个:"
          echo ${servers[*]}
          exit
        fi

    • 字符串推断:
    是否相等:
    if [ "$confirm" == "y" ] && [ "$confirm" != "n" ];do
        # do something...
    fi

    是否为空(空返回true): if [-z $string ]
    是否非空(非空返回true): if [ -n $string ]

    • 正則表達式推断
    if [[ $1 =~ ^public|industry$ ]] && [[ $3 =~ ^[yn]$ ]];then
      # do something...
    fi

    if [[ ! $deploy_more =~ [yn] ]];then
       # do something...
    fi

    • 推断文件是否存在:
    if [ ! -f target/$project.war ];then
       # do something...
    fi

    • 推断文件夹是否存在:
    if [ -d $2/webapps/$1 ];then
        # do something...
    fi

    • 推断一个文件名称(字符串)的后缀
    backup_file="/backup/java_data/$1-$today.war"
    backup_file="/backup/java_data/$1-$today.gz"

        if [ "${backup_file##*.}" = "war" ];then
          cp $backup_file $1.war
        elif  [ "${backup_file##*.}" = "gz" ];then
          tar zxvf $backup_file
        else
          echo "备份文件格式不正确"
          exit
        fi

    read 语句(读取用户输入的字符串):
    • 最简单的使用方法:读取用户输入到变量yes_or_no
    read yes_or_no

    • 提示用户输入y或n
    read -e -p "是否备份:(y/n)?" -i "y" needbackup
    (參数说明:-e:不知有什么用,但假设去掉了,-i就失效了。-p:后面接着提示语句。-i:后面接着缺省输入;最后一个參数是保存用户输入的变量。

    select 语句(提示用户从列表中选择一个):
    • 改动默认提示语(默认值是"#?"):
     PS3="请选择一个项目:"

    • 提示用户从数组中选择一个值:
      select project in ${projects[*]};do
        if [ $project ];then
          break
        fi
      done

    或加上退出条件:
     select target_ip in ${servers[*]} "Exit(退出)";do
        if [ "$target_ip" = "Exit(退出)"  ]; then
              echo "谢谢使用!Good-Bye!"
              break
            fi

        if [ $target_ip ]; then
            # do something
        fi
     done

    case 语句:
      case $project in
        public)  project_name="大众版" ;;
       logistics) project_name="配送" ;;
        misc) project_name="杂项版" ;;
      esac

    while 语句:
    • 配合正則表達式推断使用:
      while [[ ! $needbackup =~ ^[yn]$ ]];do
        read -e -p "是否备份:(y/n)?" -i "y" needbackup
      done

    • 用“...”做进度条
    echo -n "等待$port 端口打开……"
    while [ ! $pid_new ];do
      #sleep 1
      pid_new=`netstat -nlp | grep $port | awk '{print $7}' | awk -F "/" '{print $1}'`
      echo -n "…"
    done

    for语句:
    • 遍历:
    for ip_t in ${servers[*]};do
      if [ "$2" = "$ip_t" ];then
        is_ip_correct=true
        break
      fi
    done

    调用其它程序:
    • 使用``,并获得输出结果:
          PS3="请选择一个分支:"
          select branch in `svn list svn://<svn_host>/java/code/branches`;do
            if [ $branch ];then
              svn_dir="svn://<svn_host>/java/code/branches/$branch"
              project_dir=$branch
              break
            fi
          done

    • 使用$()。并获得输出结果:
    today=$(date +%Y-%m-%d/%H:%M:%S)
    svn_version=$(svn info $svn_dir | grep "Last Changed Rev:" | awk '{print $4}')

    • 无声地调用其它程序(不输出结果,即把结果输出到一个null设备中)
    rm $2/logs/m* $2/logs/l* $2/logs/h* $2/logs/catalina.2015* &>/dev/null &

    awk(用来对字符串进行切片处理,一般配合grep使用):
    • 获得以空格分隔的第四个字符串:
    svn_version=$(svn info $svn_dir | grep "Last Changed Rev:" | awk '{print $4}')

    • 获得以特殊分隔符("/")分隔的第一个字符串
     awk -F "/" '{print $1}'
    • print NF} 和 {print $NF}
      前者是输出了域个数,后者是输出最后一个字段的内容
      如:~# echo $PWD | awk -F/ '{print $NF}'

    • 获取全部端口号为 $port 的进程,并杀掉
    for pid in `netstat -nlp | grep $port | awk '{print $7}' | awk -F "/" '{print $1}'`
    do
      echo "==========================Warning========================"
      echo "无法正常关闭进程,端口:$port,直接kill掉,进程号:$pid"
      echo "==========================Warning========================"
      kill $pid
    done

    实例:
    1、倒计时:
    #!/bin/sh
    
    seconds_left=15
    
    echo "请等待${seconds_left}秒……"
    while [ $seconds_left -gt 0 ];do
      echo -n $seconds_left
      sleep 1
      seconds_left=$(($seconds_left - 1))
      echo -ne "
         
    " #清除本行文字
    done
    echo "done!"

    2、命令运行失败时自己主动重试,直到成功(比方运行svn checkout命令,可能由于网络问题不成功):
    svn checkout $svn_dir
    
    while [ ! $? -eq 0 ];do
      echo "重试……"
      svn checkout $svn_dir
    done;
    
    echo "done!"

    (原创文章,转载请注明转自Clement-Xu的博客:http://blog.csdn.net/clementad/article/details/46793827)

    很多其它的使用实例请參考:

  • 相关阅读:
    源码阅读(18):Java中主要的Map结构——HashMap容器(中)
    源码阅读(17):红黑树在Java中的实现和应用
    java中创建文件并写入的方法
    源码阅读(16):Java中主要的Map结构——HashMap容器(上)
    源码阅读(15):Java中主要的Map结构——概述
    从源码分析:Java中的AQS
    源码阅读(14):Java中主要的Queue、Deque结构——PriorityQueue集合(下)
    源码阅读(13):Java中主要的Queue、Deque结构——PriorityQueue集合(中)
    java 归并排序与快速排序
    python中的容器、可迭代对象、迭代器、生成器
  • 原文地址:https://www.cnblogs.com/cynchanpin/p/6740130.html
Copyright © 2020-2023  润新知