• shell学习


    shell学习

    Shell 是一个命令解释权,它为用户提供了一个向 Linux 内核发送请求以便运行程序界面系统级程序,用户可以用 Shell 来启动、挂起、停止甚至是编写一些程序。

    1、简单demo

    进入 Linux 终端,编写一个 Shell 脚本 hello.sh :

    #!/bin/bash 
    echo 'hello world!'
    

    运行

    # 方法1 
    sh hello.sh  
    
    # 方法2 
    chmod +x hello.sh 
    ./hello.sh
    
    

    说明

    #! 告诉系统这个脚本需要什么解释器来执行。
    文件扩展名 .sh 不是强制要求的。
    方法1 直接运行解释器,hello.sh 作为 Shell 解释器的参数。此时 Shell 脚本就不需要指定解释器信息,第一行可以去掉。
    方法2 hello.sh 作为可执行程序运行,Shell 脚本第一行一定要指定解释器。
    

    2、shell中的变量

    Shell 变量分为系统变量自定义变量。系统变量有$HOME、$PWD、$USER等。

    显示当前 Shell 中所有变量,直接在命令窗口输入命令:set

    变量名可以由字母、数字、下划线组成,不能以数字开头。

    基本语法

    • 定义变量:变量名=变量值,等号两侧不能有空格,变量名一般习惯用大写。

    • 删除变量:unset 变量名 。

    • 声明静态变量:readonly 变量名,静态变量不能unset。

    • 使用变量:$变量名

    • 将命令返回值赋给变量

      A=`ls` #反引号,执行里面的命令
      A=$(ls) #等价于反引号
      

    设置环境变量

    • export 变量名=变量值,将 Shell 变量输出为环境变量。

      vi /etc/profile
      在文件后面追加:
      export CESHI=ceshi
      
    • source 配置文件路径,让修改后的配置信息立即生效。

      source /etc/profile
      
    • echo $变量名,检查环境变量是否生效

    位置参数变量

    • $n :$0 代表命令本身、$1-$9 代表第1到9个参数,10以上参数用花括号,如 ${10}。

    • $* :命令行中所有参数,且把所有参数看成一个整体。

    • $@ :命令行中所有参数,且把每个参数区分对待。

    • $# :所有参数个数。

    • demo

      #编写 Shell 脚本 positionParam.sh:
      #!/bin/bash     
      # 输出各个参数 
      echo $0 $1 $2 
      echo $* 
      echo $@ 
      echo 参数个数=$#
      执行shell
      chmod +x positionParam.sh 
      ./positionParam.sh 10 20
      执行结果
      ./positionParam.sh 10 20 
      10 20 
      10 20 
      参数个数=2
      

    预定义变量

    在 Shell 脚本中直接引用的变量,默认值

    • $$ :当前进程的 PID 进程号。

    • $! :后台运行的最后一个进程的 PID 进程号。

    • $? :最后一次执行的命令的返回状态,0为执行正确,非0执行失败。

    • demo

      编写 Shell 脚本 preParam.sh
      vi preParam.sh 内容如下:
      #!/bin/bash     
      echo 当前的进程号=$$ 
      # &:以后台的方式运行程序 
      ./hello.sh & 
      echo 最后一个进程的进程号=$! 
      echo 最后执行的命令结果=$?
      运行结果:
      当前进程号=2234
      最后一个进程的进程号2235
      最后的命令执行结果0 # hello.sh的输出
      

    3、运算符

    • $((运算式)) 或 $[运算式]

    • expr m + n 注意 expr 运算符间要有空格

    • expr m - n

    • expr *,/,% 分别代表乘,除,取余

    • demo

      # 第1种方式 $(()) 
      echo $(((2+3)*4))   
      
      # 第2种方式 $[],推荐 
      echo $[(2+3)*4]  
      
      # 使用 expr 
      TEMP=`expr 2 + 3` 
      echo `expr $TEMP * 4`
      

    4、流程控制

    if判断

    [ condition ] 注意condition前后要有空格。非空返回0,0为 true,否则为 false 。

    demo1:

    #!/bin/bash 
    if [ 'test01' = 'test' ] 
    then
         echo '等于' 
    fi  
    
    # 20是否大于10 
    if [ 20 -gt 10] 
    then
         echo '大于' 
    fi  
    
    # 是否存在文件/root/shell/a.txt 
    if [ -e /root/shell/a.txt ] 
    then
         echo '存在' 
    fi  
    
    if [ 'test02' = 'test02' ] && echo 'hello' || echo 'world' 
    then
         echo '条件满足,执行后面的语句' 
    fi
    
    执行结果:
    大于 
    hello 
    条件满足,执行后面的语句
    

    demo2:

    #!/bin/bash
    if [ $1 -ge 60 ]
    then
        echo 及格
    elif [ $1 -lt 60 ]
    then
        echo "不及格" 
    fi
    

    case分支

    demo

    case $1 in
    "1")
    echo 周一
    ;;
    "2")
    echo 周二
    ;;
    *)
    echo 其它
    ;;
    esac
    

    for循环

    基本语法

    # 语法1
    for 变量名 in 值1 值2 值3...
    do
        程序
    done
    
    # 语法2
    for ((初始值;循环控制条件;变量变化))
    do
        程序
    done
    

    demo1

    #!/bin/bash  
    
    # 使用$* 
    for i in "$*" 
    do     
        echo "the arg is $i" 
    done 
    echo "=================="  
    
    # 使用$@ 
    for j in "$@" 
    do     
        echo "the arg is $j" 
    done
    执行结果:
    the arg is 1 2 3 
    ================== 
    the arg is 1 
    the arg is 2 
    the arg is 3
    

    demo2

    #!/bin/bash 
    SUM=0  
    for ((i=1;i<=100;i++)) 
    do     
        SUM=$[$SUM+$i] 
    done 
    
    echo $SUM
    

    while循环

    语法

    while [ 条件判断式 ]
    do
        程序
    done 
    

    demo

    #!/bin/bash
    SUM=0
    i=0
    
    while [ $i -le $1 ]
    do
        SUM=$[$SUM+$i]
        i=$[$i+1]
    done       
    echo $SUM
    

    5、读取控制台输入

    基本语法

    read(选项)(参数)

    -p:指定读取值时的提示符
    -t:指定读取值时等待的时间(秒),如果没有在指定时间内输入,就不再等待了。
    变量名:读取值的变量名
    

    demo

    #!/bin/bash
    
    read -p "请输入一个数num1=" NUM1
    echo "你输入num1的值是:$NUM1"
    
    read -t 10 -p "请在10秒内输入一个数num2=" NUM2
    echo "你输入num2的值是:$NUM2"
    输出:
    请输入一个数num1=10
    你输入num1的值是:10
    请在10秒内输入一个数num2=20
    你输入num2的值是:20
    

    6、函数

    和其它编程语言一样,Shell 编程有系统函数和自定义函数

    系统函数

    • basename 删掉路径最后一个 / 前的所有部分(包括/),常用于获取文件名

      basename [pathname] [suffx]
      basename [string] [suffx]
      如果指定 suffx,也会删掉pathname或string的后缀部分
      
    • dirname 删掉路径最后一个 / 后的所有部分(包括/),常用于获取文件路径

      dirname pathname
      如果路径中不含 / ,则返回 '.' (当前路径)
      

    自定义函数

    语法

    [ function ] funname[()]
    {
        Action;
        [return int;]
    }
    
    # 调用
    funname 参数1 参数2...
    

    demo

    #!/bin/bash
    
    function getSum(){
        SUM=$[$n1+$n2]
        echo "函数打印: $SUM"
        return $SUM
    }
    
    read -p "请输入第一个参数n1:" n1
    read -p "请输入第二个参数n2:" n2
    
    # 调用 getSum 函数
    getSum $n1 $n2
    echo "结果打印:$?"
    
    

    7、一份完整的java程序脚本

    #!/bin/bash
    #
    # description: {{ APPID }} init script
    # processname: tomcat  
    # chkconfig: 234 20 80 
    
    APPID="AppPurchaseService"
    USER="deploy"
    
    ### paths
    PROJECT_DIR=/workspace/carkey/AppPurchaseService/latest/
    PROJECT_LOG=/workspace/carkey/AppPurchaseService/
    MAIN_CLASS="com.hellobike.platform.aps.deploy.Application"
    START_OPTS="$START_OPTS -DAPPID=$APPID"
    
    cd ${PROJECT_DIR}
    
    #Memory configs
    MEM_OPTS="-Xms5120m -Xmx5120m -Xmn1706m -XX:MaxMetaspaceSize=512m -XX:MetaspaceSize=512m"
    
    #GC OPTS
    GC_OPTS="$GC_OPTS -XX:+UseConcMarkSweepGC 
    -XX:+UseParNewGC 
    -XX:+UseCMSCompactAtFullCollection 
    -XX:CMSFullGCsBeforeCompaction=0 
    -XX:CMSInitiatingOccupancyFraction=62 
    -XX:CMSTriggerRatio=70"
    
    #GC logging
    GC_OPTS="$GC_OPTS -Xloggc:${PROJECT_LOG}/logs/gc.log"
    GC_OPTS="$GC_OPTS -XX:+PrintGCDateStamps -XX:+PrintGCDetails"
    GC_OPTS="$GC_OPTS -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=${PROJECT_LOG}/logs/heapdump.hprof"
    
    # JMX OPTS
    JMX_OPTS="$JMX_OPTS -Dcom.sun.management.jmxremote.port=15005 
    -Dcom.sun.management.jmxremote.authenticate=false 
    -Dcom.sun.management.jmxremote.ssl=false 
    -Dcom.sun.management.jmxremote=true 
    -Dowl.metrics.kafka.servers=owl.kafka1.ttbike.com.cn:9092,owl.kafka2.ttbike.com.cn:9092,owl.kafka3.ttbike.com.cn:9092"
    
    
    START_OPTS="$START_OPTS -Djava.io.tmpdir=$PROJECT_DIR/temp/"
    START_OPTS="$START_OPTS -Duser.dir=$PROJECT_DIR"
    
    CLASS_PATH="$PROJECT_DIR/conf:$PROJECT_DIR/lib/*:$CLASS_PATH"
    
    
    # get pid
    getPid(){
        if [ -z $1 ]
        then
            echo "Usage: $0 process-pattern" >&2
            exit 1
        fi
    
        exc_pids="^$$$"
        curr_pid=$$
        while [ $curr_pid -gt 0 ]
        do
            curr_pid=`ps -fwwp $curr_pid|grep -v PPID|awk '{print $3}'`
            exc_pids="$exc_pids|^$curr_pid$"
        done
        curr_script=$0
        curr_script=${curr_script#.}
        curr_script=${curr_script//./\.}
    
        if [ $# -eq 1 ]
        then
            ps -efww|grep "$1"|grep '-DAPPID='|grep -Ev "grep|$curr_script"|awk '{print $2}'|grep -Ev $exc_pids
        else
            firstArg=$1
            shift
            ps -efww|grep "$firstArg "|grep "$*"|grep '-DAPPID='|grep -Ev "grep|$curr_script"|awk '{print $2}'|grep -Ev $exc_pids
        fi
    }
    
    #return value
    retval=0
    getNameFromPid(){
       nowTime1=$(date)
       tips="冲突时间"
       printf "冲突进程信息请查看:/tmp/startCrash.log
    "
    
       echo $tips$nowTime1 >> /tmp/startCrash.log
       echo "冲突进程数量:" $# >> /tmp/startCrash.log
    
       for loop in $*
       do
           ps -ef|grep $loop|grep -v grep >> /tmp/startCrash.log
       done
    }
    # start the server
    start(){
        printf 'Starting the server
    '
        pids=`getPid $APPID`
        if ! [ -z "$pids" ];then
            printf 'Existing process: %d
    ' "$pids"
            getNameFromPid $pids
            retval=1
        else
            #start
            mkdir -p "$PROJECT_DIR/temp/"
            mkdir -p "$PROJECT_DIR/logs/"
            #echo "MEM_OPTS: $MEM_OPTS"
            #echo "GC_OPTS: $GC_OPTS"
            #echo "JMX_OPTS: $JMX_OPTS"
            #echo "START_OPTS: $START_OPTS"
             chown -R deploy.deploy $PROJECT_LOG/
             chown -R deploy.deploy $PROJECT_DIR/
             chown -R deploy.deploy $PROJECT_LOG/logs/
            JAVA_CMD="nohup java -server $MEM_OPTS $GC_OPTS $JMX_OPTS $START_OPTS -Denv=pro -DAPPID=AppPurchaseService -Dfile.encoding=UTF-8 -classpath $CLASS_PATH $MAIN_CLASS $PROJECT_DIR/conf/Configure.json > $PROJECT_LOG/logs/jvm_std.log 2>&1 &"
            echo $JAVA_CMD
            if ! [ `whoami` = "deploy" ];then
              /bin/su $USER -c "mkdir -p $PROJECT_DIR/temp/"
              /bin/su $USER -c "$JAVA_CMD"
            else
              mkdir -p $PROJECT_DIR"/temp/"
              /bin/bash -c "$JAVA_CMD"
            fi
            echo "Process pid: `getPid $APPID`"
            sleep 3
            if [ -z `getPid $APPID` ]
            then
                echo "Failed to start the server"
                retval=1
            else
                echo "Finish $0"
                retval=0
            fi
        fi
    }
    
    # stop the server
    stop(){
        printf 'Stopping the server
    '
        pids=`getPid $APPID`
        if [ -z "$pids" ]
        then
            printf 'process is not running
    '
            retval=0
        else
            #stop
            max_loop=10
            for ((i=0; i<$max_loop; i++))
            do
                pids=`getPid $APPID`
                if [ -z "$pids" ]
                then
                    break;
                fi
    
                if [ $i -gt 5 ]
                then
                    _9="-9"
                fi
    
                for pid in $pids
                do
                    echo "Kill process with pid:$pid and pattern:$MAIN_CLASS"
                    if ! kill $_9 $pid
                    then
                        echo "Failed kill process with pid:$pid and pattern:$MAIN_CLASS"
                    else
                        echo "Succeed kill process with pid:$pid and pattern:$MAIN_CLASS"
                    fi
                done
    
                sleep 3
            done
    
            if [ $i -eq $max_loop ]
            then
                echo_t "Failed kill the processes $pids after try $max_loop times"
                retval=1
            else
                retval=0
            fi
        fi
    }
    
    # status for server
    status(){
        pids=`getPid $APPID`
        if ! [ -z "$pids" ];then
            printf 'server is running: %d
    ' "$pids"
        else
            printf 'server is stopped
    '
        fi
    }
    
    user_exists(){
            if id -u $1 >/dev/null 2>&1; then
            echo "1"
            else
                    echo "0"
            fi
    }
    
    # dispatch the command
    case "$1" in
        start)
        start
        ;;
        stop)
        stop
        ;;
        status)
        status
        ;;
        restart)
        stop
        start
        ;;
        *)
        printf 'Usage: %s {start|stop|restart|status}
    '
        exit 1
        ;;
    esac
    
    
    # exit
    exit "$retval"
    
    
    
    # END OF FILE
    
  • 相关阅读:
    并发编程学习笔记(七、Thread源码分析)
    并发编程学习笔记(六、线程组)
    并发编程学习笔记(五、线程中常用的方法)
    并发编程学习笔记(四、线程的优先级)
    并发编程学习笔记(三、如何安全地终止线程)
    sql server登陆账号时遇到233错误
    github上传shh公匙问题
    mysql简单复习
    idea导入jstl标签库
    山高有攀头,路远有奔头~
  • 原文地址:https://www.cnblogs.com/hhhshct/p/14320905.html
Copyright © 2020-2023  润新知