• shell脚本入门基础-1


     

    前言

    本文主要是shell脚本的一些基本语法,小编也是shell菜鸟,不当之处欢迎指正。

    一.变量

    1.环境变量

    #!bin/bash
    #环境变量
    echo "User Info :"    
    echo "user : $USER"
    echo "UID : $EUID"
    echo "home : $HOME"
    echo ''HOSTNAME''

    2.用户变量

    变量命名规则:

            由字母,数字和下划线组成;

            大小写敏感

    #!bin/bash
    var1="hello"
    var2="world"
    var3=100
    echo "$var1 $var2 $var3"

    3.特殊变量   

    变量 含义
    $0 当前脚本的文件名
    $n 传递给脚本或函数的参数。n 是一个数字
    $# 传递给脚本或函数的参数个数。
    $* 传递给脚本或函数的所有参数。
    $@ 传递给脚本或函数的所有参数。
    $? 上个命令的退出状态,或函数的返回值。
    $$

    当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。

    #!bin/bash
    
    echo " file name : $0 "
    echo " Total Number Parameters : $# "
    echo " Frist name : $1"
    echo " Quoted Values: $@ "
    echo " Quoted Values: $* " 
    echo " $? "
    echo " shell PID: $$"
    

    $@ 与 $* 的区别

    $* 和 $@ 都表示传递给函数或脚本的所有参数,不被双引号(" ")包含时,都以"$1" "$2" … "$n" 的形式输出所有参数。
    但是当它们被双引号(" ")包含时,"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;"$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数。

    #! /bin/bash
    echo '$@:'
    for i in $@
    do
        echo $i
    done
    echo '"$@:"'
    for i in "$@"
    do
        echo $i
    done  
    echo '$*:'
    for i in $*
    do
        echo $i
    done
    echo '"$*:"'
    for i in "$*"
    do
        echo $i
    done

    结果:      

    $@:
    1
    2
    3
    "$@:"
    1
    2
    3
    $*:
    1
    2
    3
    "$*:"
    1 2 3

    4. `` 与 $()

    将命令的执行结果赋值给变量的两种形式

    #!/bin/bash

    var=`date +%y%m%d`

    echo $var

    var1=$(date +%y%m%d)

    echo $var1

    二.数学计算

    1.expr

    #!/bin/bash
    # 注意变量和=之间不能有空格,expr 和 = 之间要有一个空格
    var= expr 1 + 2
    echo $var
    

    2.[ ] 与 (( ))

    #!/bin/bash
    # 
    var=$[ 1 + 2 ]
    echo $var var=$(( 3 + 4 ))
    echo $var

    3. bc

    上述两种智能计算整数,对于浮点数就要用到bc

    脚本中使用bc的格式:

    variable=`echo "option; expression" |bc` 
    #!/bin/bash
    var=`echo "scale=2;5/3" | bc`
    echo $var

    三.逻辑控制

    1.if

    1.1 if-then

    if command
    then
          command
    fi

    例:

    #!/bin/bash
    
    if date
    then
          echo "command is succeed"
    fi
    

    1.2 if -then -else  

    #!/bin/bash
    if command
    then 
          command
    else 
          command
    fi

    例:

    #!/bin/bah
    # 查找系统中是否存在httpd用户
    if grep httpd /etc/passwd
    then
        echo "httpd is exist"
    else
        echo "httpd not find"
    fi
    

    1.3 if嵌套

    #!/bin/bash
    if command
    then
        command
    elif command
        command    
    else
         command	    
    fi
    

    2.test

    功能:

          数值比较

          字符串比较

           文件比较

    格式:  

    #!/bin/bash
    test condition
    或
    [ command ]    --更常用
    

    2.1 数值比较

    比较 描述
    -eq 等于
    -ge 大于等于
    -gt 大于
    -le 小于等于
    -lt 小于
    -ne 不等于

    例:

    #!bin/bash
    date
    if [ $? -eq 0 ]
    then
         echo "command is succeed"
    fi
    #或
    if test date
    then
         echo "command is succeed"
    fi
    

    2.2 字符串比较

    比较 描述
    str1=str2 字符串是否相同  
    str1 !=str2 字符串是否不同  
    str1<str2 str1是否小于str2  
    str1>str2 str1是否大于str2

     [b>a] && echo "true"

    (注意>需要转义)

    -n str  字符串长度非零为真  [-n "abc"] && echo "str is not null"
    -z str  字符串长度为0为真   [-z ""] && echo "str is  null"

      

    2.3 文件比较

    比较 描述
    -d file 检查file是否存在并是一个目录  
    -f file 检查file是否存在并是一个目录  
    -e file 检查file是否存在  
    -r file 检查文件是否存在并可读  
    -s file  检查文件是否存在并非空  
    -w file 检查文件是否存在并可写  
    -x file 检查文件是否存在并可执行  
    -O file 检查文件是否存在并属当前用户所有  
    -G file 检查文件是否存在并且默认组与当前用户相同  
    file1 -nt file2 file1是否比file2新  

    2.4 复合条件

    [condition1] && [condition2]

    [condition1] ll [condition2]

    3.case

    格式:

    case variable in
    pattern1 | pattern2) command1 ;;
    pattern3) command2 ;;
    *) default command ;;
    esca  

    例:

    #!、bin/bash
    read -p "input something: " var
    case $var in 
    [0-9])
           echo "number";;
    [a-z]) 
           echo "str"
    *)    echo "请重新输入"
    esca

    4.for

    4.1 bash中的for

    格式:

    for var in command
    do
          command
    done

    例:

    #!/bin/bash
    #查看服务状态
    for service in apache2 mysqld zabbix-server zabbix-agent
    do
          status=$(systemctl status mysql | awk ' /Active/  {print $2,$3}' )
          echo $service $status
    done

    例:使用通配符

    #!/bin/bash
    #注意在$file上加" ",否则如果出现带空格的目录名,脚本会出错
    for file in /tmp/*
    do
         if [ -d "$file" ]
         then 
               echo " file is a directory "
         elif [ -f "$file"]
         then
               echo "$file"  is a file
          fi
    done
    

     4.2 使用c语言风格for

    #!/bin/bash 
    #单变量
    
    for (( i=1; i<=10; i++ ))
    do
         echo $i
    done
    
    #多变量
    
    for (( i =1,j=10; i<=10; i++,j-- ))
    do
        echo $i $j
    done
    

    5.while  

     例:

    #!/bin/bash
    #检查站点状态
    urls="
    https://www.baidu.com
    https://www.taobao.com
    https://www.jd.com/abc
    https://www.12306.cn/index/
    192.168.1.111
    "
    for url in $urls
    do 
         count =0
         while [ $count -lt 3 ] 
         do
              status = $(curl -I -m 10 -o /dev/null -s -w %{http_code} $url)
              if [ $status -eq 200 ]
              then
                  echo "$url ok"
                  break 1
               fi
          count = $((count +1 ))
          done
          if [ ¥count -eq 3 ]
          then
              echo  " $url Error "
          fi
    done
      
    

    6.until 

    #!.bin/bash
    var=10
    until [ $var -eq 0 ]
         do
         var = $[ $var-2 ]
         echo $var
    done
    

    7.循环控制

    7.1 break

    #!/bin/bash
    #break跳出当前循环
    #break n 跳出n层循环
    for (( i=1; i<=10; i++ ))
    do
        if [$i -eq 5]
        then
            break
        fi
        echo $i
    done 

    四 . 输入

     1.命令行参数

    例:

    #!/bin/bash
    echo $1 + 0$2 =$[ $1 +$2 ]
    
    #执行命令
    ./shell_name 3 4
    3 + 4=7

    例:

    #!/bin/bash
    #把变量位置左移
    while [ -n "$!"]
    do
         echo $1
         shift
    done
    

    2.getopts

    格式:getopts optstring variable

    optstring:选项字母,如果字母要求有参数就加一个:,要去掉错误信息的话可以再optstring前加一个:

    variable:保存当前参数

    #!/bin/bash
    #getopts用法
    #opt会保存输入的参数,如 r,i,x
    #OPTARG保存参数值
    #参数需要就在后面加一个: 如 i:
    while getopts rix: opt
    do
            case "$opt" in
            r ) echo " remove all service " ;;
            i ) echo " install service $OPTARG " ;;
            x) echo " 可执行 "   ;;
            *) echo " Unknown option :$opt " ;;
            esac
    done
    
    root@localhost:/# ./getopts.sh -i apache1
    install service apache2
    root@localhost:/# ./getopts.sh -r
    remove all service
    root@localhost:/# ./getopts.sh -a
    ./getopts.sh: illegal option -- a
    Unknown option: ?
    

    3.获得用户输入read

    3.1普通用法  

    #!/bin/bash
    read name
    echo $name
    

    3.2指定提示符

    #!/bin/bash
    read -p " Enter you name: " name
    echo " Hello $name "
    

    3.3指定超时时间

    #!/bin/bash
    if read -t 5 -p " Enter you name: " name
    then
          echo " Hello $name "
    else 
           echo " time out"
    fi
    

    3.4隐藏数据

    #!/bin/bash
    read -s -p " Enter Password: " password
    echo
    echo " $password " 

    五.输出

    现实脚本输出的方法:

     1.显示器显示

     2.将输出重定向到文件

    描述符 缩写 描述
    0 STDIN 标准输入
    1 STDOUT 标准输出
    2 STDERR 标准错误

    1.脚本中重定向

    1.1临时重定向

    使用场景:脚本中生成错误信息

    #!/bin/bash
    echo "This is an error message" >&2
    echo "This is normal output" 

    默认情况下Linux会将STDERR定向到STDOUT

    $ ./error.sh

    This is an error message
    This is normal output

    在执行脚本的时候重定向STDERR,ERR文本就会被重定向

    $ ./error.sh 2> error.log
    This is normal output
    $ cat error.log
    This is an error message

    1.2永久重定向

    用exec命令告诉shell在执行脚本期间重定向某个特定文件描述符。

    #!/bin/bash
    exec 2>errout
    echo "This is error"
    exec 1>testout
    echo "testout"
    echo "testout  to errout" >&2
    

     

    $ ./test.sh
    This is error
    $ cat errout
    testout  to errout
    $ cat testout
    testout  

     六.函数

    1.基本函数

    #!/bin/bash
    #定义方式1
    functionfoo{
         echo "This is a func "    
    }
       
    #定义方式2
    bar() {
         echo " This is another func "
    
    } 
    #函数的调用
    foo
    bar
    

     2.返回值

    1.默认退出状态码

    #!/bin/bash
    #定义方式1
    function foo{
         echo "hello world "   
    }
    foo
    echo "Exit status is $?"

    2.使用return命令

    #!/bin/bash
    #定义方式1
    function foo{
         echo " hello world " 
         return 1   
    }
    
    foo
    echo " Exit status is $?"
    

      

     3.使用函数输出

    #!/bin/bash
    #定义方式1
    function foo{
         echo " hello world " 
         return 1   
    }
    #赋值给变量
    result = foo
    echo " Exit status is $result "
    

     3.变量

    1.传参

    #!/bin/bash
    function status{
          systemctl status $1
    
    }
    status  sshd
    

    2.局部变量与全局变量

    #!/bin/bash
    #定义全局变量
    hostname = "web"
    function foo {
         str = " hello "
         #使用local定义局部变量
         local user = "https"
         echo " $hostname "
         echo " $user "
    
    }
    foo
    #在函数内部定义的局部变量不能再全局使用
    
    echo " $str $user" 
    

    3.数组变量

    #解决方法
    #!/bin/bash
    function foo {
         arr =$@
         echo "Thr received array is ${ arr[ * ] } "
    }
    myarr = (1 2 3 4 )
    foo ${ myarr[*] }

    七.控制脚本

    1.处理信号

    1.1. 查看LInux信号

    kill -l 

    在Linux 编程时会遇到最常见的Linux系统信号

    信 号	值	描 述	                   触发
    1	SIGHUP	挂起进程	
    2	SIGINT	终止进程	                   Ctrl + C
    3	SIGQUIT	停止进程	
    9	SIGKILL	无条件终止进程	
    15	SIGTERM	尽可能终止进程	
    17	SIGSTOP	无条件停止进程,但不是终止进程	
    18	SIGTSTP	停止或暂停进程,但不终止进程	   Ctrl+Z
    19	SIGCONT	继续运行停止的进程	
    

    1.2.脚本执行

    1.脚本执行

    bash filename.sh 或

    chmod +x filename.sh

    ./ilename.sh 

    2.后台运行脚本

    ./test.sh &

    nohup ./test.sh &

    附:退出状态

    可以使用$? 查看上一个命令的退出状态码

    状态码 含义
    0 命令成功结束
    1 通知未知错误
    2 误用shell命令
    126 命令不可执行
    127 没有找到命令
    128+x Linux信号x的严重错误
    130 命令通过Ctrl+C终止
    255 退出状态码越界
  • 相关阅读:
    计算两个日期之间相差的年数月数天数(JS实现)
    一次源码编译PHP折腾记
    Spring的JdbcTemplate与其事务
    spring aop的配置
    动态代理的几种方式
    移动互联网后端技术
    web front end stack web 前段技术概览
    BIO | NIO | AIO (Java版)
    什么是javascript中的闭包?
    get、put、post、delete含义与区别
  • 原文地址:https://www.cnblogs.com/liushui0306/p/14469865.html
Copyright © 2020-2023  润新知