• shell脚本后台启动停止jar包并且计算运行时间


    源代码

    #!/bin/bash
    
    JAR_NAME=demo.jar
    
    start() {
      begin=`date +%s`
    
      nohup java -jar "$JAR_NAME" 2>&1 &
    
      i=0
      while [ 1 ]
      do
        PID=$(ps -ef | grep "$JAR_NAME" | grep -v grep | awk '{print $2}')
    
        if [[ -n $PID ]]; then
          array=(${PID//\n/ })
          if test $[i] -eq 0; then
            echo -ne "${#array[*]} $JAR_NAME is running\r"
          else
            echo -ne "${#array[*]} $JAR_NAME has been running for $i seconds\r"
          fi
        else
          end=`date +%s`
          duration=$[ $end - $begin ]
          echo -e "\nFinished in $duration seconds."
          exit
        fi
        sleep 1
        i=`expr $i + 1`
      done
    }
    
    stop() {
      PID=$(ps -ef | grep "$JAR_NAME" | grep -v grep | awk '{print $2}')
    
      if [[ -n $PID ]]; then
        for item in $PID
        do
          kill -9 $item
          echo "kill -9 $item"
        done
      else
        echo "$JAR_NAME not running."
      fi
    }
    
    tips() {
      echo "-------------------------------------"
      echo ""
      echo "sh $0 [commands]"
      echo ""
      echo "Support commands :"
      echo "start  -启动当前项目"
      echo "stop  -停止当前项目"
      echo ""
      echo "-------------------------------------"
    }
    
    case "$1" in
    "start")
      start
      ;;
    "stop")
      stop
      ;;
    *)
      tips
      ;;
    esac
    

    执行sh demo.sh start 启动命令:

    执行 sh demo.sh stop 停止命令:

    执行停止命令后:

    接下来,我为大家解析一下脚本中的代码。

    源码细节解析

    Shell变量

    定义变量:

    JAR_NAME=demo.jar
    

    注意点:不要把写C/C++/Java定义变量时留空格的习惯带到编写 shell 脚本中来。
    JAR_NAME = demo.jar,在 = 前后留空格是定义 shell 变量的大忌,会抛出 JAR_NAME: command not found 这样的错误。
    显然,你在 JAR_NAME 后面留空格,Bash 把它当做命令来执行,= 和 demo.jar 被看作命令的参数了。

    Shell中的“switch ... case”

    case ... esac 为多选择语句,与其他语言中的 switch ... case 语句类似,是一种多分支选择结构。
    每个 case 分支用右圆括号开始,用两个分号 ;; 表示 break,即执行结束,跳出整个 case ... esac 语句,esac(就是 case 反过来)作为结束标记。
    case ... esac 语法格式如下:

    case 值 in
    模式1)
        command1
        command2
        ...
        commandN
        ;;
    模式2)
        command1
        command2
        ...
        commandN
        ;;
    esac
    

    如果值无法匹配模式,使用星号 * 捕获该值,再执行后面的命令。因此,我们简化一下上面的代码并保存在 test.sh 中:

    #!/bin/bash
    
    case "$1" in
    start)
     echo start
     ;;
    stop)
     echo stop
     ;;
    *)
     echo others
     ;;
    esac
    

    实验结果如下,除了 sh test.sh startsh test.sh stop,其他参数都会进入 * 分支内。

    [geekziyu@mylinuxhost ~]$ sh test.sh
    others
    [geekziyu@mylinuxhost ~]$ sh test.sh start
    start
    [geekziyu@mylinuxhost ~]$ sh test.sh stop
    stop
    

    单引号''和双引号""

    看我的代码,我有时候会写单引号'',有时候会写双引号"",有时候又不写。
    这是不是和你们学习 javascript 或者其他语言,定义字符串的方式有些不同呢?
    接下来,看一个例子,了解啥时候要加引号,啥时候不加引号?

    #!/bin/bash
    
    name=geekziyu
    
    echo hello $name
    echo 'hello $name'
    echo "hello $name"
    

    执行 sh test.sh 执行结果为:

    hello geekziyu
    hello $name
    hello geekziyu
    
    引号名称 引号效果
    单引号 单引号定义为所见即所得,单引号内部的内容原样输出,被单引号引起来的内容不管时变量还是常量都不会发生替换
    双引号 双引号引用的内容,是先把内容中的命令、变量等解析出结果,然后再输出最终内容

    对于本例而言,这里的双引号完全可以省略,第一条命令echo hello $name与第三条命令echo "hello $name"效果一致。

    echo -ne "\r"

    简化一下代码量:

    #!/bin/bash
    
    JAR_NAME=demo.jar
    
    echo -ne "$JAR_NAME is running\r"
    sleep 1
    echo -ne "$JAR_NAME has been running for 1 seconds\r"
    sleep 1
    echo -ne "\n"
    

    效果如下图:

    点击了解更多 echo -ne 的命令效果

    ``和$() 用语句给变量赋值

    显示地给变量直接赋值,比如 val=123
    除此以外,还可以用语句给变量赋值:

    #!/bin/bash
    
    begin=`date +%s`
    echo $begin
    i=0       #输出结果例如 1653223046
    i=`expr $i + 1`
    echo $i   #输出结果 1
    

    了解更多 菜鸟教程 Shell 变量
    了解更多 菜鸟教程 Shell 基本运算符 算数运算符 及 表达式计算工具 expr

    计算数组长度 ${#array[*]}

    Shell 数组用括号来表示,元素用"空格"符号分割开,语法格式如下:

    array_name=(value1 value2 ... valuen)

    #!/bin/bash
    
    array=(1 2 3)
    echo "数组长度等于 ${#array[*]}"  # 数组长度等于 3
    echo "数组长度等于 ${#array[@]}"  # 数组长度等于 3
    

    了解更多 菜鸟教程 Shell 数组

    $0表示脚本文件名称

    本文源码中用到了代码 echo "sh $0 [commands]"

    shell内置变量 变量含义 执行脚本示例 变量对应值
    $0 Shell本身的文件名 ./test.sh 1 test.sh
    $1~$n 添加到Shell的各参数值。
    $1是第1个参数、$2是第2个参数…
    ./test.sh 1 2 $1值等于1
    $2值等于2

    参考自 linux shell $0怎么输出,linux shell中$0,$?,$!等的特殊用法

    分隔字符串

    awk有内置的变量。对于每一个记录,即行,分隔空白字符分隔记录默认情况下,它存储在$1..$n变量。如果该行有4个词,它会被存储在$1$2$3$4。$0表示整行。
    awk '{print $2}' 表示打印每一行的第二列,行与行之间肯定是用换行符\n作为分隔符。

    ${parameter//pattern/string}
    用 string 来替换 parameter 变量中所有匹配的 pattern。

    本例中${PID//\n/ }就是把换行符 \n 替换成为空格
    然后,array=(${PID//\n/ }) 外层的 array=(value1 value2 value3) 就是普通的数组赋值操作了。

    了解更多 【shell】shell字符串分割|文件分割|剪切|截取
    了解更多 Shell awk命令详解(格式+使用方法)

    shell变量 字符串替换

    用 string 来替换第一个匹配的pattern

    ${parameter/pattern/string}
    

    开头开始匹配 parameter 变量中的 pattern,匹配上后就用 string 来替换匹配的 pattern (仅替换第一个匹配到的 pattern)

    ${parameter/#pattern/string}
    

    结尾开始匹配 parameter 变量中的 pattern,匹配上后就用 string 替换匹配的 pattern (仅替换第一个匹配到的 pattern)

    ${parameter/%pattern/string}
    

    用 string 来替换 parameter 变量中所有匹配的 pattern

    ${parameter//pattern/string}
    

    了解更多 shell变量的子串的删除/替换

  • 相关阅读:
    异常以及异常处理框架探析
    ArcGis Server10 for java初试
    C#制作鹰眼全过程(带注释)
    flex remoteobject 因默认设置而调用失败
    ExecutorService.submit(Callable).get()不并发执行
    学习《The Flex, Spring, and BlazeDS full stack》-1
    java.lang.NoSuchMethodError: org.hibernate.mapping.SimpleValue.<init>(Lorg/hibernate/mapping/Table;)V
    用内置jetty运行项目struts2提示找不到Action
    二分查找
    排序
  • 原文地址:https://www.cnblogs.com/kendoziyu/p/16292394.html
Copyright © 2020-2023  润新知