• shell 编程入门


    shell 介绍

    在计算机科学中,shell 是一个命令解释器,shell 脚本是 shell 编程的一种实现

    shell 是位于操作系统和应用程序之间,是他们二者最主要的接口,shell 负责把应用程序的命令解释给操作系统,将操作系统处理后的结果解释给应用程序,所以,shell 相当于是应用程序与操作系统之间的媒介(翻译官的角色)

     

    linux 内一般是 bash,mac 是 zsh,然后还有 windows 的cmd,不过最近 windows 发布了完整内核的 linux 子系统 WSL 2

    查看当前系统的 shell 类型:echo  $SHELL

    shell 脚本

    定义:可执行的 linux 命令不在命令行下执行,而是通过一个文件执行时,称这个文件是 shell 脚本

    一般用 vim 直接打开文件即可创建一个脚本,例如 vim  start_service.sh 表示创建一个开启服务的脚本,脚本的内容自然是各种可执行的命令

    #!/bin/bash
    echo 'start service~'

     注释:单行使用 #,多行注释有两种方法,分别是 :<<! ... !  和 :<<字符 ... 字符

    #!/bin/bash
    echo '1'
    :<<!
    echo '3'
    echo '4'
    !
    echo '5'

    脚本执行方式:

      bash  /path/test.sh     使用 bash shell 执行脚本(脚本无可执行权限,或脚本内容首行没有指定 shell ,也可以用)

      /path/test.sh         指定路径下执行脚本(需要脚本文件具有可执行权限)

      source  /path/test.sh    加载shell脚本文件内容,使shell脚本内容环境和当前用户环境一致

    编写规范:

    脚本首行必须指定脚本解释器:#!/bin/bash

    首行后面要有脚本的基本信息等说明内容(常见的注释信息:脚本名称、脚本功能描述、脚本版本、脚本作者、联系方式等),尽量不要使用中文,防止乱码(linux服务器一般不支持中文)

    代码编写规范,逻辑清晰

      成对的内容一次性写出来,如:(), [], {}, ' ', " ", ` `

      [ ] 中括号两端要有空格,编写时即可留出空格,然后再退格写内容

      流程控制语句一次性写完,再添加具体内容

    变量

    变量分为本地变量,全局变量, shell 内置变量

    本地变量是当前系统的某个环境下才能生效的变量,作用范围小,包含普通变量和命令变量

      普通变量:

        方式一:变量名=变量值    (变量值必须是一个整体,中间没有特殊字符)

        方式二:变量名='变量值'     (变量值是什么,就是什么)

        方式三:变量名="变量值"    (如果变量值中含有可解析的变量A,那么会先解析变量A,将A的结果和变量中其它值组成一个整体,重新赋值给左边的变量名)

      命令变量:

        方式一:变量名=$(命令)     推荐用法,执行命令,将结果赋值给左边的变量名

        方式二:变量名=`命令`       是反引号,不推荐

    全局变量是当前系统所有环境下都能生效的变量

    查看全局变量命令:env

    定义全局变量的三种方法:

    export  变量=值 (这种定义是临时的,在关闭 shell 时失效)

    [root@centos7 ~]# VALUE='global variabel'
    [root@centos7 ~]# export VALUE
    [root@centos7 ~]# env | grep 'VALUE'
    VALUE=global variabel
    [root@centos7 ~]# export VALUE_TWO='global variabel'
    [root@centos7 ~]# env | grep 'VALUE'
    VALUE=global variabel
    VALUE_TWO=global variabel
    [root@centos7 ~]#

    设置永久的(对所有用户生效),用 vim 修改 /etc/profile 文件,添加变量

    export CLASSPATH=./JAVA_HOME/lib;$JAVA_HOME/jre/lib

    修改文件后,立即生效需要运行 source  /etc/profile

    设置永久的(对单一用户生效),用 vim 修改 ~/.bash_profile 文件,与上面操作一样 

    shell 内置变量

    本地变量,全局变量都是需要先定义,然后使用,那么 shell 内置变量就是直接使用实现某种具体功能的,如:$0,$n,$#

    $0    获取当前执行的 shell 脚本文件名,包括脚本路径

    $n    获取当前执行的 shell 脚本的第 n 个参数值,n=1...9,当 n 为 0 时表示脚本的文件名,如果 n 大于 9 就要用大括号括起来 ${10}

    $#    获取当前执行的 shell 脚本中参数的总个数

    $?    获取执行上一个命令的返回值(0 为成功,非 0 为失败)

    #!/bin/bash
    echo "my scripts name is:$0"
    
    # current args amount
    echo $#
    
    # get target args
    echo $1
    echo $2
    echo $3
    echo $4
    
    # excute result
    echo $?
    
    执行效果
    [root@centos7 shell_exercise]# bash remaks.sh a b c d
    my scripts name is:remaks.sh
    4
    a
    b
    c
    d
    0
    [root@centos7 shell_exercise]#

    变量内容的截取(切片)

    ${变量名:起始位置:截取长度}

    ${file:0:5}        从第1个字符开始,截取5个字符
    ${file::5}         从第1个字符开始,截取5个字符
    ${file:5:5}        从第6个字符开始,截取5个字符
    ${file:5}          从第6个字符开始,截取后面所有的字符
    ${file:0-5}        从倒数第5个字符开始,截取后面所有的字符
    ${file:0-6:3}      从倒数第6个字符开始,截取之后的3个字符

    变量默认值

    执行脚本时,往往会在脚本后面指定参数;但如果没有给定参数,那么可以设定默认值(类似于缺省参数)

    场景一:执行脚本时,如给定了脚本中变量 a 的值,那么就将值赋予 $a,如果没有给定,那么在脚本中可以设定默认值

    格式:${变量名:- 默认值}

      如果我在命令后面补充了参数 n,那么输出内容是:receive args is n

      如果我在命令后面没有补充参数,那么输出的内容是:receive args is 2

    #!/bin/bash
    a=$1
    echo "receive args is ${a:-2}"

    场景二:无论是否给定变量 a 的值,都输出默认值(感觉这个没有意义)

    格式:${变量名 + 默认值}

    #!/bin/bash
    a=$1
    echo "receive args a is ${a+666}"

    变量的查看与删除

    查看:

      $变量名    在命令行 / 脚本中使用

      "$变量名"    在命令行 / 脚本中使用

      ${变量名}    echo  "data access ${变量名} f "

      "${变量名}"    推荐使用方式  

    删除: unset  变量名

    表达式

    使 shell 脚本具备一定的逻辑、运算能力

    测试语句

    [ 条件表达式 ]

    条件成立返回 0;不成立返回 1

    [root@centos7 shell_exercise]# [ 1 = 1 ]
    [root@centos7 shell_exercise]# echo $?
    0
    [root@centos7 shell_exercise]# [ 1 = 2 ]
    [root@centos7 shell_exercise]# echo $?
    1
    [root@centos7 shell_exercise]# 

    逻辑表达式

    用来判断多个条件之间的依赖关系,常见的逻辑表达式有:&&,||

    命令1  &&  命令2    (如果命令1执行成功,才执行命令2;如果命令1执行失败,那么不执行命令2)

    命令1  ||  命令2       (如果命令1执行成功,那么不执行命令2;如果命令1执行失败,才执行命令2)  

    Demo:[ 1 = 1 ]      (空格不能掉)

    [root@centos7 shell_exercise]# [ 1 = 1 ]  && echo "0"
    0
    [root@centos7 shell_exercise]# [ 1 = 2 ]  && echo "0"
    [root@centos7 shell_exercise]# [ 1 = 1 ]  || echo "0"
    [root@centos7 shell_exercise]# [ 1 = 2 ]  || echo "0"
    0
    [root@centos7 shell_exercise]# 

    文件表达式

    -f  根据输入内容,判断当前目录是否存在这个文件

    [root@centos7 shell_exercise]# [ -f test.sh ] && echo "0"
    0
    [root@centos7 shell_exercise]# [ -f test.123 ] && echo "0"

    -x  根据输入内容,判断当前目录是否存在这个文件,并且可执行

    -d  根据输入内容,判断当前目录是否存在这个子目录

    数值操作符

    常见选项有:大于、小于、等于、不等于

    n1  -eq  n2

    n1  -gt  n2

    n1  -lt  n2

    n1  -ne  n2

    字符串比较

    str1 == str2    (str1 和 str2 字符串内容是否相同)

    str1 != str2     (不相同)

    [root@centos7 shell_exercise]# [ a == a ]
    [root@centos7 shell_exercise]# echo $?
    0
    [root@centos7 shell_exercise]# [ a != a ] 
    [root@centos7 shell_exercise]# echo $?
    1
    [root@centos7 shell_exercise]# 

    计算表达式

    进行算数计算

    $(())  $((计算表达式))    或者

    let     let  计算表达式    (let 更方便)

    [root@centos7 shell_exercise]# echo $((100 / 5))
    20
    [root@centos7 shell_exercise]# i=0
    [root@centos7 shell_exercise]# let i=i+99
    [root@centos7 shell_exercise]# echo $i
    99
    [root@centos7 shell_exercise]# 

    流程控制

    shell 中,流程控制语句主要分为两种:

      简单的:判断和循环

      复杂的:函数

    if 判断语句

    if

    if [ 条件 ]
    then
         命令  
    fi

    if  else

    if [ 条件 ]
    then
        命令1
    else
        命令2
    if

    if  elif  else

    if [ 条件 ]
    then
        命令1
    elif [条件2]
    then
        命令2
    else
        命令3
    fi

     生产场景demo

    #!/bin/bash
    
    if [ "$1" == "start" ];then
        echo "start..."
    elif [ "$1" == "stop" ];then
        echo "stop..."
    elif [ "$1" == "restart" ];then
        echo "restart..."
    else
       echo "Usage: bash $0 [ start | stop | restart ]"
    fi

    case 选择语句

    多 if 语句使用的时候,代码量很多,case 语句整体看起来效果会好一些

    #!/bin/bash
    
    case "$1" in
        start)
            echo "start..."
            ;;
        stop)
            echo "stop..."
            ;;
        restart)
            echo "restart..."
            ;;
        *)
            echo "Usage: bash $0 [ start | stop | restart ]"
            ;;
    esac

    for 循环语句

    遍历列表

    #!/bin/bash
    
    for i in $(ls /root)
    do
        echo "${i}"
    done

    while 循环语句

    #!/bin/bash
    a="$1"
    
    while [ "${a}" -lt 100 ]
    do
        echo "${a}"
        a=$((a+1))
    done

    until 循环语句(与 while 功能重复,需要控制好临界点)

    #!/bin/bash
    a="$1"
    
    until [ "${a}" -gt 100 ]
    do
        echo "${a}"
        a=$((a+1))
    done

    函数

    函数就是将一些命令组合起来实现某种功能的方式,是脚本编写中非常重要的部分

    函数格式(注意:函数调用的时候不要加括号):

    #!/bin/bash
    func_test(){
        echo "my name is johny, I 19 yesrs old"
    }
    func_test

    函数传参(内部传参)

    #!/bin/bash
    func_test(){
        echo "my name is $1, I $2 yesrs old"
    }
    func_test anson 20

    函数传参(脚本传参)

    #!/bin/bash
    func_test(){
        echo "my name is $1, I $2 yesrs old"
    }
    
    func_test $1 $2

    # 脚本传参
    bash case.sh anson 20

    写一个启动脚本:

    #!/bin/bash
    
    # local variabel
    args="$1"
    
    # help information
    usage(){
        echo "the script is used as follows: $0 [ start|stop|restart ]"
    }
    
    # main func
    if [ $# -eq 1 ];then
        case "${args}" in
            start)
                echo "service startup..."
            ;;
    
            stop)
                echo "service stoped..."
            ;;
    
            restart)
                echo "service restart..."
            ;;
    
            *)
                usage
            ;;
        esac
    else
        usage
    fi

    end~ 

     

    每天都要遇到更好的自己.
  • 相关阅读:
    【转】Entity Framework教程
    【转】《我的WCF之旅》博文系列汇总
    【转】无废话WCF系列教程
    【转】 wpf系列-入门
    基于Extjs的web表单设计器 第五节——数据库设计
    基于Extjs的web表单设计器 第四节——控件拖放
    基于Extjs的web表单设计器 第三节——控件拖放
    基于Extjs的web表单设计器 第二节——表单控件设计
    基于Extjs的web表单设计器 第一节
    基于Extjs的web表单设计器
  • 原文地址:https://www.cnblogs.com/kaichenkai/p/10848143.html
Copyright © 2020-2023  润新知