• shell编程


    php和java主要实现功能
    shell简化管理操作

    shell 基础

    查看当前使用的shell:echo $SHELL
    查看支持的shell: cat /etc/shells

    #!/bin/bash声明使用bash开头,若当前使用其它shell时,执行这个脚本时,也会自动使用bash

    赋予执行权限 chmod +x hello.shchmod 755 hello.sh
    执行: ./hello.sh 或调用bash来执行 bash hello.sh

    Bash变量

    变量命名规则

    • 变量名必须以字母或下划线开头,名字中间只能由字母、数字和下划线组成
    • 变量名的长度不得超过255个字符
    • 变量名在有效范围内必须是唯一的
    • 在Bash中,变量的默认类型都是字符串型

    用户自定义变量

    变量名=变量值

    注意:=两边不能有空格,变量值,可以用引号包起来,也可以不需要,但当变量值中含有空格时,一定需要引起来

    变量的调用:在变量名前加$
    echo $name

    变量叠加

    x=123
    x="$x"456
    x=${x}456
    echo $x
    
    # 注意,不能直接使用+,这会将加号直接当成字符串拼接在一起  
    

    变量查看
    env # 查看环境变量
    set # 查看当前所有的变量,包括用户自定义变量与环境变量
    set -u # 如果设置此选项,调用未声明变量时会报错(默认无任何提示)

    变量删除unset 变量名(不需要加$)

    环境变量

    环境变量最好都设置为大写
    对系统生效的环境变量名和变量作用是固定的

    设置环境变量

    export 变量名=变量值  
    # 或
    变量名=变量值
    export 变量名
    

    删除与查看与用户自定义变量一样

    常用环境变量

    • HOSTNAME: 主机名
    • SHELL: 当前的shell
    • TERM: 终端环境
    • HISTSIZE: 历史命令条数
    • SSH_CLIENT: 当前操作系统环境是用ssh连接的,这里记录客户端IP
    • SSH_TTY: ssh连接的终端pts/1
    • USER: 当前登录的用户

    PATH环境变量:系统查找命令的路径,冒号分隔
    echo $PATH # 查看PATH环境变量
    PATH="$PATH":/root/sh # 增加PATH变量的值

    PS1环境变量: 命令提示符设置echo $PS1

    • d: 显示日期,格式为“星期 月 日”
    • H: 显示完整的主机名。如默认主机名“localhost.localdomin”
    • : 显示24小时制时间,格式为“HH:MM:SS”
    • A: 显示24小时制时间,格式为“HH:MM”
    • u: 显示当前用户名
    • w: 显示当前所在目录的完整名称
    • W: 显示当前所在目录的最后一个目录名
    • $: 提示符。如果是root用户会显示提示符为#,普通用户为$

    语系变量
    locale # 查询当前系统语系
    LANG: 定义系统主语系的变量
    LC_ALL: 定义整体语系的变量

    echo $LANG # 查看系统当前语系
    locale -a | more # 查看Linux支持的所有语系

    位置参数变量

    位置参数变量 作用
    $n n为数字,$0代表命令本身,$1-$9代表第一到第九个参数,十以上的参数需要用大括号包含,如${10}
    $* 这个变量代表命令行中所有的参数,$*把所有的参数看成一个整体
    $@ 这个变量也代表命令行中所有的参数,不过$@把每个参数区分对待
    $# 这个变量代表命令行中所有参数的个数
    # !/bin/bash
    
    # 注意需要使用双引号括起来,否则,其含义发生变化
    for i in "$*"
    do
        # 只循环一次
        echo "the parameters is: $i"
    done
    
    
    # 注意需要使用双引号括起来,否则,其含义发生变化
    for i in "$@"
    do
        echo "parameter: $i"
    done
    

    预定义变量

    预定义变量 作用
    $? 最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了。
    $$ 当前进程的进程号(PID)
    $! 台后运行的最后一个进程的进程号(PID)

    read: 接收键盘输入
    read [选项] 变量名
    -p: 在等待read输入时,输出提示信息
    -t: 秒数,read命令会一直等待用户输入,使用此选项可以指定等待时间
    -n:字符数,read命令只接受指定的字符数,就会执行
    -s:隐藏输入的数据,适用于机密信息的输入

    read -p "please input your passwd: " -t 30 -n 6 -s passwd

    shell运算符

    declare 命令

    declare声明变量类型

    declare [+/-][选项] 变量名
    -: 给变量设定类型属性
    +: 取消变量的类型属性
    -a: 将变量声明为数组型
    -i: 声明为整数型
    -x: 声明为环境变量
    -r: 声明为只读变量
    -p: 显示指定变量的被声明类型

    # 声明整数型  
    a=1
    b=2
    declare -i c=$a+$b # 注意=号与+号两边都不能有空格
    echo $c
    
    # 声明数组变量
    movie[0]=zp
    movie[1]=tp
    declare -a movie[2]=live
    
    # 查看数组
    echo ${movie}
    echo ${movie[2]}
    echo ${movie[*]}
    
    # 声明环境变量
    declare -x test=123 # 和export作用相似,但其实是declare命令的作用
    declare -p # 列出系统中所有变量的类型
    
    # 声明为只读属性,一般不要使用
    declare -rx test=123 # 给ro赋予只读属性,但是注意只读属性会让变量不能修改,不能删除,甚至不能取消只读属性
    declare +r test # 会报错,不能取消只读属性
    
    # 查询变量的属性
    declare -p # 查询所有变量的属性 
    declare -p 变量名 # 查询指定变量的属性
    

    数值运算的方法

    方法1: 声明变量类型

    # 声明整数型  
    a=1
    b=2
    declare -i c=$a+$b # 注意=号与+号两边都不能有空格
    echo $c
    
    

    方法2: expr或let数值运算工具

    a=1
    b=2
    d=$(expr $a + $b) # 注意+号两侧必须有空格
    echo $d
    
    

    方法3: $(( 运算式 ))$[运算式]

    a=1
    b=2
    f=$((a+b)) # +号两侧有没有空格都可以
    echo $f
    
    

    推荐使用$((运算式))

    运算符

    优先级 运算符 说明
    13 -+ 单目负、单目正
    12 !, ~ 逻辑非,按位取反或补码
    11 *, /, % 乘、除、取模
    10 +, - 加、减
    9 <<, >> 按位左移、按位右移
    8 <=, >=, <, > 小于或等于、大于或等于、小于、大于
    7 ==, != 等于、不等于
    6 & 按位与
    5 ^ 按位异或
    4 | 按位或
    3 && 逻辑与
    2 || 逻辑或
    1 =, +=, -=, *=, /=, %=, &=, ^=, |=, <<=, >>= 赋值、运算且赋值

    变量测试

    一般情况不需要使用
    在脚本优化时才使用

    环境变量配置文件

    修改配置文件后,必须注销重新登录才能生效,使用source命令可以不用重新登录
    source 配置文件. 配置文件

    环境变量配置文件简介

    常用配置文件

    • /etc/profile
    • /etc/profile.d/*.sh
    • ~/.bash_profile 只对当前用户有效
    • ~/.bashrc 只对当前用户有效
    • /etc/bashrc

    环境变量配置文件的功能

    配置文件加载顺序

    正常登录,配置文件加载顺序:
    /etc/profile --> /etc/profile.d/*.sh --> /etc/profile.d/lang.sh --> /etc/locale.conf~/.i18n
    /etc/profile --> ~/.bash_profile --> ~/.bashrc --> /etc/bashrc --> 命令提示符

    使用su命令切换用户,不是完整登录
    /etc/bashrc --> /etc/profile.d/*.sh --> /etc/profile.d/lang.sh --> /etc/locale.conf~/.i18n

    /etc/profile

    主要是针对登录做配置

    • USER变量
    • LOGNAME变量
    • MAIL变量
    • PATH变量
    • HOSTNAME变量
    • HISTSIZE变量
    • umask: 查看系统默认权限(创建文件时的默认权限)
    • 调用/etc/profile.d/*.sh文件

    umask权限: 四位,第一位为系统特殊权限,后三位为默认权限

    1. 文件最高权限为666,x权限必须由管理员授权
    2. 目录最高权限为777
    3. 权限不能使用数字进行换算,而必须使用字母
      文件最高权限: 666: rw-rw-rw-
      umask值: 022: ----w--w-
      最终创建文件权限: rw-r--r--
    4. umask 定义的权限,是系统默认权限中准备丢弃的权限

    ~/.bash_profile

    加载~/.bashrc
    将家目录下bin目录添加到环境变量
    PATH=$PATH:$HOME/.local/bin:$HOME/bin
    export PATH

    ~/.bashrc

    自定义别名
    加载/etc/bashrc

    /etc/bashrc

    • PS1变量
    • umask
    • PATH变量
    • 未登录shell,则调用/etc/profile.d/*.sh文件

    其他配置文件

    ~/.bash_logout 注销时生效的环境变量配置文件
    如添加 history -c,退出后清除历史命令

    ~/.bash_history 历史命令保存文件
    正确登出后,会将本次登录使用的命令,保存到这个文件

    /etc/issue 本地终端警告信息,远程登录不起作用

    转义符 作用
    d 显示当前系统日期
    s 显示操作系统名称
    l 显示登录的终端号,这个比较常用
    m 显示硬件体系结构,如i386、i686等
    显示主机名
    o 显示域名
    显示内核版本
    显示当前系统时间
    u 显示当前登录用户的序列号

    /etc/issue.net 远程终端警告信息
    转义符在/etc/issue.net中不能使用
    是否显示此信息,由ssh的配置文件/etc/ssh/sshd_config决定,加入Banner /etc/issue.net行才能显示(需要重启SSH服务service sshd restart)

    /etc/motd 登录后欢迎信息
    不管是本地登录,还是远程登录,都可以显示此信息

    正则表达式

    grep、awk、sed等命令可以支持正则表达式
    ls、find、cp不支持正则,只能使用shell自已的通配符

    通配符有*?[]

    正则: http://www.cnblogs.com/chencye/category/839826.html

    字符处理

    字符截取命令

    cut

    cut [选项] 文件 列提取
    -f: 列号,提取第几列,若取多列,则列号以英文逗号间隔
    -d: 分隔符(默认为制表符),按照指定分隔符分割列,必须是单个字符

    # 获取/bin/bash的所有普通用户名  
    grep "/bin/bash" /etc/passwd | grep -v "root" | cut -f 1 -d ":"
    
    # cut默认使用制表符分割,所以下面这条命令,不能分隔  
    df -h | cut -f 5
    
    # cut只会按照-d指定的串,进行分割,如下面命令,只以一个空格进行分割,所以只会取到第一列 (使用awk)
    df -h | cut -f 1,3 -d " "
    

    awk

    测试test.txt

    [chencye@centos7 empty]$ cat test.txt 
    ID      name
    1       a
    2       b
    3       c
    

    printf
    printf '输出类型输出格式' 输出内容
    输出类型:
    %ns: 输出字符串。n是数字,指代输出几个字符
    %ni: 输出整数。n是数字,指代输出几个数字
    %m.nf: 输出浮点数。m和n是数字,指代输出的整数位数和小数位数
    输出格式:
    a: 输出警告声音
    : 输出退格键
    f: 清除屏幕
    : 换行
    : 回车
    : 水平输出退格键
    v: 垂直输出退格键

    printf '%s' $(cat test.txt) 不调整输出格式
    printf '%s %s ' $(cat test.txt) 将输出与前面显示格式一样

    print在每个输出后自动加入一个换行符(linux默认没有print命令),printf标准格式输出命令

    awk
    命令: awk '条件1 {动作1} 条件2 {动作2}...' 文件名

    awk '{printf $1 " " $2 " "}' test.txt 没有条件,所有都输出
    df -h | grep "/dev$" | awk '{print $5}' | cut -f 1 -d "%" 查看磁盘已使用百分比

    BEGIN 在所有动作执行之前,先执行这个动作

    cat /etc/passwd | awk 'BEGIN{FS=":"}{print $1 " " $3}' FS设置分隔符,如果没有BEGIN,将不起作用

    END 在所有动作执行之后,最后再执行这个动作

    条件: 运算符

    cat test.txt | grep -v "name" | awk '$1==1 {print $2 "的ID是1"} $1==3 {print $2 "的ID是2"}'

    字符增删改查命令

    sed 轻量级流编辑器
    主要用来将数据进行选取、替换、删除、新增的命令

    sed [选项] '[动作]' 文件名

    选项:
    -n 一般sed命令会把所有数据都输出到屏幕,如果加入此选择,则只会把经过sed命令处理的行输出到屏幕
    -e 允许对输入数据应用多条sed命令编辑
    -i 用sed的修改结果直接修改读取数据文件,而不是由屏幕输出

    动作:
    a 追加,在当前行后添加一行或多行
    c 行替换,用c后面的字符串替换原数据行
    i 插入,在当前行前插入一行或多行。 d:删除,删除指定的行
    p 打印,输出指定的行
    s 字串替换,用一个字符串替换另外一个字符串。 格式为行范围s/旧字串/新字串/g (和vim中的替换格式类似)

    # 以下均未加-i参数,都不会修改原文件
    
    sed -n '2p' test.txt # 查看文件第2行  
    sed -n '2,4p' test.txt # 查看文件第2行到第4行  
    sed '2a piaoliang jiushi renxing' test.txt # 在第2行后,加入一行,没加-i,不会修改原文件  
    sed '4c last line' test.txt # 将第4行,整行替换  
    sed '4s/c/cc/g' test.txt # 将第4行中的所有c替换为cc
    sed -e 's/a/A/g;s/b/B/g' test.txt # 将所有的a替换为A,并且将所有b替换为B。多个动作使用分号隔开  
    

    去除字符串两边的空格
    echo " abc " | sed 's/^s*//g' | sed 's/s*$//g'

    排序与统计

    sort
    sort [选项] 文件名
    -f 忽略大小写
    -n 以数值型进行排序,默认使用字符串型排序
    -f 反向排序
    -t 指定分隔符,默认制表符
    -k n[,m] 按照指定的字段范围排序。从第n字段开始,m字段结束(默认到行尾)

    sort /etc/passwd
    sort -r /etc/passwd
    sort -t ":" -k 3,3 /etc/passwd
    sort -n -t ":" -k 3,3 /etc/passwd
    

    wc
    wc [选项] 文件名
    -l 只统计行数
    -w 只统计单词数
    -m 只统计字符数

    流程控制语句

    两种判断格式

    test -e ./test.txt
    [ -e ./test.txt ] # 推荐使用这种

    文件判断

    按照文件类型判断 常用-d-e-f

    选项 作用
    -b 文件是否存在,并且是否为块设备文件
    -c 是否为字符设备文件
    -d 常用选项,目录是否存在
    -e 常用选项,文件是否存在
    -f 常用选项,普通文件是否存在
    -L 是否为符号链接文件
    -p 是否为管道文件
    -s 文件是否存在,并且是否为非空
    -S 文件是否存在,并且是否为套接字文件
    # 第一个判断命令正确执行,则输出yes,否则输出no  
    [ -e /etc/passwd ] && echo "yes" || echo "no"
    

    按照文件权限进行判断 常用-r-w-x

    选项 作用
    -r 判断文件是否存在,并且拥有读取权限
    -w 判断文件是否存在,并且拥有写权限
    -x 判断文件是否存在,并且拥有执行权限
    -u 判断文件是否存在,并且拥有SUID权限
    -g 判断文件是否存在,并且拥有SGID权限
    -k 判断文件是否存在,并且拥有SBit权限

    两个文件之间进行比较

    选项 作用
    文件1 -nt 文件2 文件1的修改时间是否比文件2的新
    文件1 -ot 文件2 文件1的修改时间是否比文件2的旧
    文件1 -ef 文件2 判断文件1是否和文件2的INODE号一致,可以理解为两个文件是否为同一个文件。这个判断用于判断硬链接是很好的方法

    整数之间比较

    选项 作用
    整数1 -eq 整数2 是否相等
    -ne 是否不相等
    -gt 前一整数数是否大于后一整数
    -lt 是否小于
    -ge 是否大于等于
    -le 是否小于等于

    字符串判断

    选项 作用
    -z 字符串 是否为空
    -n 字符串 是否为非空
    串1 == 串2 是否相等
    串1 != 串2 是否不相等
    name=chencye
    [ -z "$name" ] && echo "yes" || echo "no"
    [ "chencye" == "$name" ] && echo "yes" || echo "no"
    
    # 使用正则,匹配param值中是否包含this
    [[ $param =~ "this" ]] && echo "yes" || echo "no"
    

    与或非

    选项 作用
    判断1 -a 判断2 逻辑与,判断1和判断2都成立,为真
    判断1 -o 判断2 逻辑或,判断1和判断2有一个成立,为真
    ! 判断 逻辑非,使用原始判断式取反

    if

    fi结尾
    then如果放在[]同一行的后面,则需要使用;分开,换行则不需要

    单分支

    if [ 条件判断 ]; then
        程序
    fi
    
    # 或
    
    if [ 条件判断 ]
        then
    	程序
    fi
    

    多分支

    if [ 条件判断1 -a 需同时成立的条件 ]; then
    	执行程序1
    elif [ 条件判断2 ]; then
    	执行程序2
    else
    	执行程序3
    fi
    

    示例1:判断登录用户是否root

    #!/bin/bash
    name=$(env | grep "USER" | cut -d "=" -f 2)
    if [ "$name" == "root" ]; then
        echo "Current user is root."
    fi
    

    示例2:判断分区使用率

    #!/bin/bash
    # 统计根分区使用率
    
    # 获取根分区使用率
    rate=$(df -h | grep "/$" | awk '{print $5}' | cut -d "%" -f 1)
    
    if [ $rate -gt 80 ]; then
        echo "Warning! / is full !!"
    fi
    

    判断apache是否启动

    # 使用这种方式时,注意文件命名不能有httpd
    # 可以使用80端口
    test=$(ps aux | grep httpd | grep -v grep) 
    if [ -n "$test" ]; then
    	echo "$(date) httpd is ok!" >> /tmp/autostart-acc.log
    else
    	/etc/rc.d/init.d/httpd start &> /dev/null
    	echo "$(date) restart httpd !!" >> /tmp/autostart-err.log
    fi
    

    case

    case $变量名 in
        值1 )
    	    执行程序1
    		;;
    	值2 | 值3 )
    		执行程序2
    		;;
    	* )
    		如果都不是以上值,则执行此程序
    		;;
    esac
    

    for

    语法1

    for 变量 in 值1 值2 值3...
        do
    	    程序
    	done
    
    # 示例
    for i in 1 2 3 4 5
        do
    	    echo $i
    	done
    

    示例1:批量解压

    #!/bin/bash
    # tar_for.sh
    
    cd ~/tar
    ls *.tar.gz > ls.log
    ls *.tgz >> ls.log
    
    for name in $(cat ls.log)
        do
    	   tar -zxf $name &> /dev/null
    	done
    rm -rf ~/tar/ls.log
    

    语法2

    for (( 初始值; 循环控制条件; 变量变化 ))
        do
    		程序
    	done
    
    # 从1加到100
    #!/bin/bash
    sum=0
    for (( i=1; i<=100; i=i+1))
        do
    		sum=$(( $sum+$i ))
    	done
    echo $sum
    

    示例2:批量添加删除指定数据的用户

    #!/bin/bash
    read -p "Please input user name: " -t 30 name
    read -p "Please input the number of users: " -t 30 num
    read -p "Please input the password of users: " -t 30 pass
    
    if [ -n "$name" -a -n "$num" -a -n "$pass"]; then
    	if [ -n "$(echo $num | grep -P "^d+$")" ]; then
    		for (( i=1; i<=$num; i=i+1))
    		    do
    				/usr/sbin/useradd $name$1 &> /dev/null
    				echo $pass | /usr/bin/passwd --stdin $name$i &> /dev/null
    			done
    	fi
    fi
    
    #!/bin/bash
    # 删除所有普通用户
    for user in $(cat /etc/passwd | grep /bin/bash | grep -v root)
    	do
    		userdel -r $user
    	done
    

    while与until

    while: 一直循环,直到条件式不成立

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

    until: 一直循环,直到条件式成立

    until [ 条件判断式 ]
    	do
    		程序
    	done
    
  • 相关阅读:
    MaaS系统概述
    流处理认识
    事务补偿
    Hystrix原理与实战
    RPC概念和框架
    git remote: error: hook declined to update
    Unity CombineTexture
    Windows Powershell统计代码行数
    unity面试题二
    unity面试题一
  • 原文地址:https://www.cnblogs.com/chencye/p/6123823.html
Copyright © 2020-2023  润新知