zoukankan      html  css  js  c++  java
  • BASH 基本语法

    本节内容

    1.  什么是shell script

    2.  变量

    3.  运算符

    4.  流程控制

    5.  函数

    6.  计划任务 crontab

    一  什么是shell script

    将OS命令堆积到可执行的文件里,由上至下的顺序执行文本里的OS命令,就是脚本

    再加上些智能(条件/流控)控制,就变成了智能化脚本

    read -p 'please input hostname: ' name
    hostnamectl set-hostname $name
    二  变量

     

    part1为何要有变量

    程序的运行就是一些状态的变量 --> 用变量值的变化去表示

    part2变量命名规则

    以字母或下划线开头,剩下的部分可以是:字母、数字、下划线

    最好遵循下述规范:

      1. 以字母开头

      2. 使用下划线做单词连接

      3. 同类型的用数字区分

      4. 对于文件最好加上扩展名  例如 sql_bak.tar.gz,  log_bak.tar.bz2

     

    part3 系统变量

    set:显示所有变量

    env:环境变量

     

    part4 变量赋值

    VARNAME=VALUE

    echo $VARNAME

    删除变量 unset VARNAME

     

    part5 常用系统变量

    PATH  -->  第三方命令搜索路径
    PWD   -->  当前路径
    LANG  -->  字符编码 en_US.UTF-8

    HOME        -->  家目录
    HISTSIZE    -->  历史命令条数
    PS1             -->  命令提示符 [root@myname ~]
    IFS              -->  域分隔符 是空格,换行,TAB键的合集

     

    part6  全局变量与局部变量

    当前用户进入bash后自己定义的变量,与系统变量(固化到文件里,启动时加载)不同

    export var_name=var_value   #  export 声明全局变量

    var_name=var_vale                # 声明局部变量

    [root@localhost ~]# gender='male'               #  在爹这个位置定义一个局部变量gender
    [root@localhost  ~]# export money=1000   #  在爹这个位置定义一个全局变量money
    [root@localhost  ~]# bash                               #  切换到子bash
    [root@localhost  ~]# echo $gender              #  在儿子这里看它爹的局部变量gender,结果为空->看不到

    [root@localhost  ~]# echo $money              #  在儿子这里看它爹的全局变量money,可以看到
    1000
    [root@localhost  ~]# export hobby='readding'  #  在儿子这里定义一个全局变量hobby
    [root@localhost  ~]# exit                                   # 退出,进入爹的bash环境
    exit
    [root@localhost  ~]# echo $hobby                    # 爹是看不到儿子的export的,儿子的儿子可以看到

    [root@localhost  ~]#

     

    part7  定义变量的边界

    [root@myname ~]# moeny=10000
    [root@myname ~]# echo $moneyyuan

    [root@myname ~]# echo ${money}yuan
    10000yuan
    [root@myname ~]#

     

    part8  数据类型

    bash中的变量无须声明,拿来就用,默认的变量都会时是字符类型,还可以有数字类型。普通脚本,这两种类型够用

     

    实例:获取men_used

    [root@myname ~]# free
    total used free shared buff/cache available
    Mem: 999936 529440 111152 9552 359344 239252
    Swap: 2097148 124208 1972940
    [root@myname ~]# mem_used=`free | awk 'NR==2{print $3}'`
    [root@myname ~]# echo $mem_used
    529844

     

    三 运算符

    part1 算数运算符

      +

      -

      *

      /

      %

    [root@www ~]# echo $[3+1]
    4

    part2 关系操作

    >  <  <=  >=  ==   !=  &&  ||  要与(())连用才能达到效果

    test命令相关,[]可以达到相同效果

    -gt  -lt  -le  -ge  -eq  -ne  -a  -o

    [root@www ~]# x=1;y=2;a=10;b=5
    [root@www ~]# [ $x -lt $y -a $a -gt $b ]
    [root@www ~]# echo $?
    0

    part3  赋值运算符  

    (( ))  里面不用写$,就可以取变量值

    ((x+=1))

    ((x-=1))

    ((x*=2))

    ((x/=2))

    ((x%=2))

    [root@www ~]# x=1
    [root@www ~]# ((x=x+1))
    [root@www ~]# ((x=x+1))
    [root@www ~]# echo $x
    3

    part4  shell里面的所有计算器

    a=$[1+2]

    a=$((x+=1))

    expr 1 + 2

    浮点运算,如内存使用率,bc    yum install -y bc

    [root@www ~]# echo 'scale=2;3/10'|bc -l       # scale=2,保留2位小数
    .30
    [root@www ~]#

    实例:求内存的百分比

    [root@www ~]# free
                  total        used        free      shared  buff/cache   available
    Mem:         999936      456368      136924        9272      406644      329564
    Swap:       2097148      150356     1946792
    [root@www ~]# free | awk 'NR==2{print $2}'
    999936
    [root@www ~]# mem_total=`free | awk 'NR==2{print $2}'`
    [root@www ~]# mem_used=`free | awk 'NR==2{print $3}'`
    [root@www ~]# echo $mem_total 
    999936
    [root@www ~]# echo $mem_used 
    456752
    [root@www ~]# echo "scale=2;$mem_used/$mem_total" | bc -l
    .45
    [root@www ~]# echo "scale=2;$mem_used/$mem_total" | bc -l | cut -d. -f2
    45
    [root@www ~]# mem_per=`echo "scale=2;$mem_used/$mem_total" | bc -l | cut -d. -f2`
    [root@www ~]# echo ${mem_per}%
    45%
    [root@www ~]#

    part5 测试操作

    命令执行后会返回到一个系统变量中$?  如果$?值为0 表示命令执行成功,否则为失败

    part5-1 测试文件状态

    test -d  /etc  等价于 [ -d /etc  ]   然后用echo $? 查看结果状态    #  目录是否存在

    -d  目录   [ -d /etc ]

    -s  文件长度 > 0、非空

    -e  文件 [ -d /etc/passwd ]

    -f   普通文件[ -f /etc/passwd ]

    -r  当前用户是否读权限  [ -r /etc/passwd ]

    -w  当前用户是否写权限  [ -w /etc/passwd ]

    -x  当前用户是否执行权限  [ -x /etc/passwd ] 

    part5-2  测试字符串

    =  两个字符串相等
    != 两个字符串不相等
    -z  空串
    -n  非空串

    part5-3  测试数值

    -eq 等于

    -ne 不等于

    -gt 大于

    -lt  小于

    -ge 大于等于

    -le 小于等于

    -a 并列

    -o 或者

     

    四 流程控制

    part1 分支流程

    #!/bin/bash
    var='/etc/passwd'
    if [ -f $var ]
        then
            echo "$var is regular file"
    elif [ -b  $var ]
        then
            echo "$var is block file"
    elif [ -d $var ]
        then
            echo "$var is directory"
    elif [ -h $var ]
        then
            echo "$var is link file"
    else
        echo "$var is unkown"
    fi

    说明:

    • if...else 只有一个分支会执行

    • if 后面有then  else后面没有then

    • 最后有个fi

    以空格为单位 读取文本输入参数 $1 $2 $3 ... ${10}

    [root@localhost temp]# cat b.sh
    #/bin/bash
    echo $1
    echo $2
    echo $3
    echo ${10}
    echo ${11}
    [root@localhost temp]# ./b.sh 1 2 3 4 5 6 7 8 9 10 11
    1
    2
    3
    10
    11

    说明:

    $$  进程pid

    $*   所有参数

    $@  所有参数

    $#   参数个数

    $?   上一条命令执行结果

    简易启动nginx服务

    #/bin/bash
    ps aux | grep nginx | grep -v 'grep'
    if [ $? -ne 0 ]
        then
            systemctl start nginx
    if

    part2 循环结构

    循环重复地做某件事

    part2-1 while循环

    while :
    do
        clear
        free
        sleep 1
    done

    1.   while死循环

    #!/bin/bash
    var1=AAA
    var2=BBB
    var3=CCC
    while :
    do
        clear
        echo -e "A:${var1}
    B:${var2}
    C:${var3}"
        temp=$var1
        var1=$var2
        var2=$var3
        var3=$temp
        sleep 1
    done

    2.  打印1 - 10

    #!/bin/bash
    count=1
    while [ $count -le 10 ] do echo $count ((count++)) done

    3.  登录 运行命令

    #!/bin/bash
    while :
    do
        read -p "please input your username:  " username
        read -p "please input your password:  " password

    # 验证输入的有效性
    if [ -z $username ] || [ -z $password ] then echo "usrename or password is none." continue fi
    if [ $username = 'alex' -a $password = '123456' ]
    # 用户名密码验证正确 then echo
    "Login successfully.Welcome $username"
    # 正确进行业务处理 while : do read -p "please input your cmd: " cmd if [ "$cmd" = 'quit' ] then break fi $cmd done else
    # 用户名密码验证错误 echo "Wrong username or password" fi done

    part2-2 for循环

    1. echo  1到100

    #!/bin/bash
    for i in {1..100}  # 1-100
    do
        echo $i
    done
    #!/bin/bash
    for i in `ls /boot` # ls /boot 命令结果
    do
        echo $i
    done
    #!/bin/bash
    for i in {2..253}
    do
        ping -c1 192.168.100.$i &> /dev/null
        if [ $? -ne 0  ]
            then
                echo "192.168.100.$i is available"
        fi
    done

    part2-3 case语句

    #!/bin/bash
    read -p ">>: " name
    case $name in
    root)
    echo "welcome root"
    ;;
    admin)
    echo "welcome admin"
    ;;
    default)
    echo "welcome default"
    ;;
    *)
    echo "no user $name"
    esac

    part2-4 综合到一起,制作一个简单的菜单功能

    #!/bin/bash
    echo "script name: `basename $0`"
    echo "version 1.0"
    echo "date 2017-10-09"
    echo "Author: Tom"
    while read -p "(h for help): " var
    do
        case $var in 
            p|P|cpu|CPU)
                echo -e "
    
    "
                grep 'model name|cpu MHz|processor' /proc/cpuinfo |sort |uniq
                echo -e "
    
    "
            ;;
            m|m|mem|MEM)
                echo -e "
    
    "
                free
                echo -e "
    
    "
            ;;
            d|D|disk|DISK)
                echo -e "
    
    "
                df -Th
                echo -e "
    
    "
            ;;
            h|H|help|HELP)
                echo -e "
    	command	action
    
    "
                for i in cpu mem disk
                do
                echo -e "	$i	${i}_info"
                done
                echo -e "	help	this help page.."
                echo -e "	quit	exit !!.."
                echo -e "
    
    "
            ;;
            q|Q|quit|exit)
                exit
            ;;
            *)
                echo -e "
    $var Enter Error...
    "
        esac
    done
    五  函数
    #!/bin/bash
    
    function start(){
        echo "start..."
    }
    
    function install(){
        echo "install..."
    }
    
    if [ "$1" = 'start' ]
    then
        start
    
    elif [ "$1" = 'install' ]
    then
       install
    
    else
       echo "cmd not found"
    fi

    说明:

    1.  交互命令行的函数 function abc(){echo 'aaa';echo 'bbb';}; abc ,另外脚本文件中也可以定义函数

    2.  set 查看定义的函数;unset function_name 取消函数定义

    3.  向函数传递参数就像脚本使用变量位置 $1, $2, $3, ... $9

    4.  函数返回状态  echo $?,成功一般是返回0,定义自定义return 值

    六  计划任务crontab

    什么是计划任务

    后台运行,到了预定时间就会自动执行的任务,前提是:事先手动将计划任务设定好,这就用到了crond服务

     

    计划任务分为两类:系统级和用户级

    无论是系统级还是用户级的cron计划都是文本文件。

    系统的计划文件存放在 /etc/crontab路径下,用户的计划文件存放在/var/spool/cron/用户名

    root用户可以直接对文件进行修改来编写计划任务也可以使用 crontab -e命令,而普通用户只能使用后者

    [root@localhost ~]# crontab -e -u root         # 编辑 root 用户的计划任务

    [root@localhost ~]# crontab -l -u root          # 查看 root 用户的计划任务

     

    crontab任务配置基本格式:

    *  *  *  *  *  command

    分钟(0-59)  小时(0-23)  天(1-31)  月(1-12)  星期(0-7,0和7表示星期天)  命令

    参 数: 
    -e  编辑该用户的计时器设置

    -l  列出该用户的计时器设置

    -r  删除该用户的计时器设置

    -u <用户名称>  指定要设定计时器的用户名称

    注意:

    1.   查看计划任务的执行:tail -f /var/log/cron

    2.   写计划任务时,命令必须加上绝对路径,否则会出现这种情况:从日志中看,确实触发了计划任务的执行,但是命令却没有执行成功,

    比如* * * * * reboot就会出现这种情况,需要将reboot写成/usr/sbin/reboot

     

    crontab例子:

    30 21 * * * /usr/local/etc/rc.d/apache restart      # 每晚的21:30 重启apache
    
    45 4 1,10,22 * * /usr/local/etc/rc.d/apache restart # 每月1、10、22日的4 : 45重启apache
    
    10 1 * * 6,0 /usr/local/etc/rc.d/apache restart     # 每周六、周日的1 : 10重启apache
    
    0,30 18-23 * * * /usr/local/etc/rc.d/apache restart # 每天18 : 00至23 : 00之间每隔30分钟重启apache
    
    0 23 * * 6 /usr/local/etc/rc.d/apache restart       # 每星期六的11 : 00 pm重启apache
    
    * 23-7/1 * * * /usr/local/etc/rc.d/apache restart   # 晚上11点到早上7点之间,每隔一个小时的每分钟重启 apache
    
    0 */1 * * * /usr/local/etc/rc.d/apache restart      # 每一小时重启apache
    
    0 11 4 * mon-wed /usr/local/etc/rc.d/apache restart # 每月的4号与每周一到周三的11点重启apache
    
    0 4 1 jan * /usr/local/etc/rc.d/apache restart         # 一月一号的4点重启apache
    
    */30 * * * * /usr/sbin/ntpdate 210.72.145.44           # 每半小时同步一下时间
    
    0 */2 * * * www /usr/bin/somecommand >> /dev/null 2>&1 # 以用户www的身份每两小时就运行某个程序:
    
    
    0 1 * * * /home/testuser/test.sh    # 每天1点调用/home/testuser/test.sh
    
    */10 * * * * /home/testuser/test.sh # 每10钟调用一次/home/testuser/test.sh
    
    30 21 * * * /usr/local/etc/rc.d/lighttpd restart      # 每天的21:30重启lighttpd
    
    45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart # 每月1、10、22日的4 : 45重启lighttpd
    
    10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart     # 每周六、周日的1 : 10重启lighttpd
    
    0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart # 上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启apache。
    
    0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart  # 上面的例子表示每星期六的11 : 00 pm重启lighttpd
    
    * */2 * * * /usr/local/etc/rc.d/lighttpd restart # 每两小时的每分钟重启lighttpd
    
    0 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart   # 晚上11点到早上7点之间,每隔一小时重启lighttpd
    
    0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart # 每月的4号与每周一到周三的11点重启lighttpd
    
    0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart      # 一月一号的4点重启lighttpd
    
    */30 * * * * /usr/sbin/ntpdate 210.72.145.44          # 每半小时同步一下时间

    更多信息

    http://www.cnblogs.com/linhaifeng/p/6602149.html 

  • 相关阅读:
    CCF-Python的内置函数们
    CCF2019-03-Python题解
    Find a Number (记忆化+BFS)
    LeetCode15:三数之和(双指针)
    LeetCode:不用加号的加法(位运算)
    剑指Offer43:1~n整数中1出现的次数(数位DP)
    LeetCode190:颠倒二进制(位运算分治! 时间复杂度O(1))
    LeetCode5716:好因子的最大数目(数学、快速幂)
    python学习笔记:python的字符串拼接效率分析
    LeetCode1806:还原排列的最少操作步数(置换群 or 模拟)
  • 原文地址:https://www.cnblogs.com/jonathan1314/p/7606907.html
Copyright © 2011-2022 走看看