SHELL 笔记

作者: FyK_21f8 | 来源:发表于2021-09-03 20:12 被阅读0次

    shell笔记

    判断语句

    # 判断字符串是否为空
    if [ -z "${STR}" ];then
        echo "STR IS NULL"
    else
        echo "STR IS NOT NULL, VALUE IS ${STR}"
    fi
    
    # 判断两个字符串是否相等
    if [ "${STR}" == "${TARGET}" ];then
        echo "EQUALS"
    else
        echo "NOT EQUALS"
    fi
    
    # 两个数字比较, -eq 相等, -ne 不相等, -gt 大于, -lt 小于, -ge 大于等于, -le 小于等于
    if [ $NUM1 -eq $NUM2 ]; then
        echo "$NUM1 = $NUM2"
    elif [ $NUM1 -gt $NUM2 ]; then
        echo "$NUM1 > $NUM2"
    else
        echo "$NUM1 < $NUM2"
    fi
    
    # 判断文件夹是否存在,不存在则创建
    if [ -d ${DIR_PATH} ]; then
        echo "${DIR_PATH} EARLY EXISTS"
    else
        echo "${DIR_PATH} NOT EXISTS, TRY TO MAKE DIR"
        mkdir -p ${DIR_PATH}
    fi
    
    # 判断文件是否存在,不存在则创建
    if [ -f ${FILE_PATH} ]; then
        echo "${FILE_PATH} EARLY EXISTS"
    else
        echo "${FILE_PATH} NOT EXISTS, TRY TO TOUCH FILE"
        touch ${FILE_PATH}
    fi
    

    运算

    # 运算符 + - * / %
    # 方法1,`expr ...`
    RESULT=`expr ${NUM1} + ${NUM2}`
    echo $RESULT
    
    # 方法2,$(( ... ))
    RESULT=$((${NUM1} / ${NUM2}))
    echo $RESULT
    

    选择语句

    # if 语句
    if [ ${NUM} -eq 1 ]; then
        echo "${NUM1}等于1"
    elif [ ${NUM} -gt 1 ]; then
        echo "${NUM1}大于1"
    else
        echo "${NUM1}小于1"
    fi
    
    # case语句
    PAY="weixin"
    case "${PAY}" in
        "weixin") 
            echo "微信支付"
            ;;
        "alipay")
            echo "支付宝支付"
            ;;
        # 匹配多个 | 隔开
        "card" | "bank")
            echo "银行卡支付"
            ;;
        *)
            echo "其他支付方式"
            ;;
    esac
    

    循环语句

    # 1 for
    # 1.1 普通for
    NUM=5
    for (( INDEX=0; INDEX < $NUM; INDEX ++))
    do
        echo $INDEX
    done
    
    # 1.2 for in
    for VAR in str1 str2 str3
    do
        echo $VAR
    done
    
    # while
    while (( $NUM <= 15))
    do
        echo ${NUM}
        # let 中执行表达式,使用变量不需要加上$
        let "NUM++"
    done
    
    # 3 死循环
    # 3.1 while true
    while true
    do
        echo "loop"
    done
    
    # 3.2 while :
    while :
    do
        echo "loop"
    done
    
    # for (( ; ; ))
    for (( ; ; ))
    do
        echo "loop"
    done
    

    将shell字句执行结果复制给变量

    # 方法1, ``
    NOW_DATE_TIME=`date "+%Y-%m-%d %H:%M:%S"`
    echo $NOW_DATE_TIME
    
    # 方法2,$()
    NOW_DATE_TIME=$(date "+%Y-%m-%d %H:%M:%S")
    echo $NOW_DATE_TIME
    

    shell简单传参

    编号 变量符号 释义
    1 $0 脚本的名称
    2 $n 获取第n个参数的值
    3 $* 获取所有的参数
    4 $# 这个脚本执行时的入参个数
    5 $$ 这个脚本执行时的PID
    6 $@ 和$*一样,但是能当做数组使用

    字符串'',""的区别

    # ''中的字符串会原封不动的输出,变量不会生效
    STR="String"
    FINAL_STR='${STR}'
    echo $FINAL_STR
    # 输出结果 ${STR}
    
    # ""变量可生效
    FINAL_STR="${STR}"
    echo $FINAL_STR
    # 输出结果 String
    

    数组

    # 定义数组
    ARRAY=("NAME" "AGE" "ADDRESS")
    
    # 修改数组的元素
    ARRAY[0]="NIKE_NAME"
    
    # 读取数组元素
    ELEMENT_VALUE=${ARRAY[0]}
    echo ${ELEMENT_VALUE}
    
    # 获取数组长度
    LENGTH_1=${#ARRAY[@]}
    LENGTH_2=${#ARRAY[*]}
    echo ${LENGTH_1} ${LENGTH_2}
    
    # 遍历数组的3种方式
    # 方法1
    for element in ${ARRAY[@]}
    do
            echo $element
    done
    
    # 方法2
    for (( int=0;int < ${#ARRAY[@]};int ++))
    do
            echo ${ARRAY[int]}
    done
    
    # 方法3
    for index in "${!ARRAY[@]}"
    do
            echo ${ARRAY[$index]}
    done
    

    输入重定向

    # 把打印结果HELLO WORD重定向到/home/a.txt中,文件不存在则创建,路径不存在报错
    echo "HELLO WORD !" > /home/a.txt
    # > 清空原文本后写入, >> 追加到文件尾部
    
    # 以运行jar包命令为例子(这个应该经常用吧)
    nuhup java -jar xxxxx.jar ${JAVA_OPTS} >/dev/null 2>&1 &
    # nohup xxxx & 让程序后台运行
    # >/dev/null ,正常nohup 运行会输出nohup.out日志文件,不想输出则将日志重定向到/dev/null这个文件中,无底洞
    # 2>&1表示正常日志和错误日志输出文件合并,2为错误文件的描述符,1为标准文件输出的描述符
    # >/dev/null 2>&1 表示合并后重定向到无底洞,一般不需要输出日志时使用
    
    # 清空某个文件的快捷方式
    echo "" > /path/file
    

    文件属性

    -rwxr-xr-x 1 root root 5051 Sep  3 14:56 execute_agg.sh
    # 第一个字符 - 标识为文件类型,还有其他类型: d 为文件夹, l 为链接
    # 接下来的字符以三个为一组,出现三组,每组均为rwx的组合(三个字母顺序不会变), r代表读(read),w代表写(write),x代表可执行(execute),对应的位置上有字母则标识有字母对应的权限,-代表没有权限.第一组表示该文件拥有者用户的权限,第二组是用户组的权限,第三组为其他用户的权限.
    
    # 更改文件用户归属(-R 递归)
    chown -R [用户名] [文件名或者文件夹]
    
    # 更改所属组
    chgrp -R [用户组名] [文件或者文件夹]
    
    # 修改文件权限
    # 其中u=rwx表示所有者的权限为可读可写可执行,依次类推g为用户组,o为其他用户,a为u,g,o都改变
    chmod u=rwx,g=rw,o=r /home/a.txt
    # 进修改某个用户的某个权限 chmod [u/g/o/a][+/-][r/w/x] [file_path]
    chmod o+x /home/a.txt
    # rwx也可以用数字表示简化权限设置, r=4,w=2,x=1;所以 r--=4, -w-=2, --x=1, rw-=6,r-x=5,-wx=3,rwx=7
    chmod 777 /home/a.txt
    

    磁盘相关

    # 查看内存使用情况
    free -h
    
    # 查看磁盘使用情况
    df -h
    
    # 查看某个目录下所有文件的使用空间情况du -h [path], 查看当前目录[path]可忽略
    du -h /home
    
    # 如果不想递归展开,只查看当前文件夹层级(文件直接显示打下,文件夹显示文件夹内所有文件的大小总和) du -h [path/*],当前文件夹可忽略路径直接*
    du -sh *
    
    # 排序,这里不能加h,因为h将单位转换成KB/MB/GB会影响排序,后面还可以加 | head或者 | tail查看最后最顶部10条记录
    du -s * | sort -nr 
    

    vim相关常用操作

    功能 运行模式 命令
    搜索 命令模式/底行模式 /[要搜索的内容]
    上一个搜索目标 进入搜索结果后 N
    下一个搜索目标 进入搜索结果后 n
    回到文档第一行 命令模式 gg
    跳到文档最后一行 命令模式 shift + g
    向上翻页 命令模式 ctrl + b
    向下翻页 命令模式 ctrl + f
    剪切光标所在行(可当删除一行用) 命令模式 dd
    复制光标所在行 命令模式 yy
    粘贴剪切或复制的内容 命令模式 p
    进入编辑模式 命令模式 i
    回到命令模式 底行模式/编辑模式 Esc
    进入底行模式 命令模式 shift + :
    退出(有修改则无法退出) 底行模式 q
    不保存退出 底行模式 q!
    保存退出 底行模式 wq
    强制保存退出 底行模式 wq!
    取消搜索结果的高亮显示 底行模式 noh
    显示行号 底行模式 set nu
    取消显示行号 底行模式 set nonu

    yum安装软件

    # 安装 -y 不需要询问直接安装
    yum install -y xxxxx
    
    # 删除
    yum remove -y xxxxx
    
    # 更新软件,如果不写软件名直接更新整个系统包括linux内核yum update xxxx# 只下载安装包不执行安装需要有downloadonly插件, yum install -y yum-download安装
    yum install xxx -downloadonly -downloaddir=/home/installers
    
    # 安装下载后的rpm包(需要先cd 到离线rpm包所在的目录)
    yum localinstall *.rpm
    
    # 或者使用
    rmp -ivh *.rpm
    

    awk字符串切割的使用

    # awk -F '[分割符号]' '{print $n}', $n 代表第几个参数# 读取conf.properties中name=jack的值
    NAME=`cat conf.properties | grep 'name' | awk -F '=' '{print $2}'`
    echo ${NAME}
    
    # 假设要kill flume这个应用
    ps -ef | grep 'flume' | grep -v 'grep' | awk -F ' ' '{print $1}' | xargs -n kill -9
    
    # 判断某个应用是否启动,没有启动则启动
    ps -ef | grep docker | grep -v "grep"| wc -l
    

    wc 用于计算字数

    # wc 可配置参数, -l 统计行数, -w 统计词数# wc -l 计算行数,判断应用是否启动
    DOCKER_COUNT=`ps -ef | grep docker | grep -v "grep"| wc -l`
    if [ $DOCKER_COUNT -gt 0 ]; then
        echo "docker is started"
    else
        systemctl start docker
    fi
    

    将某个字符串按照某个字符切割成数组

    # 按照逗号进行分割
    taskids="1001,1002,1003"TASK_IDS=${taskids//,/ }
    

    大小写转换

    STR="AbC"
    
    # 大写转小写
    STR=`echo $STR | tr 'A-Z' 'a-z'`
    echo $STR
    
    # 小写转大写
    STR=`echo $STR | tr 'a-z' 'A-Z'`
    echo $STR
    

    日期转换操作

    # 将date转换yyyy-MM-dd HH:mm:ss格式时间
    CURRENT_DATE=`date "+%Y-%m-%d %H:%M:%S"`
    echo "$CURRENT_DATE"
    
    # 将yyyy-MM-dd HH:mm:ss格式时间转换成时间戳
    END_TIME=`date -d "$CURRENT_DATE" +%s`
    echo "${END_TIME}"
    

    读取用户输入内容

    # read会让用户进入输入模式,并使用变量接收用户输入值
    echo "PLEASE INPUR YOUR NAME"
    read NAME
    echo ${NAME}
    

    cp 命令直接覆盖文件不需要询问

    # 在写shell脚本的时候执行cp命令,经常遇到文件存在时,提示是否需要覆盖,而导致脚本无法往下执行,centos 的cp执行的时候通过别名的方式会自动加上-i
    # 要达到不需要询问直接覆盖,使用/使别名失效即可
    \cp /home/a.txt /home/b.txt
    

    sed -i 替换文件内容

    a.txt文件内容

    name:jack
    namespace-name:dev-center
    nick-name:tom
    

    sed -i 操作

    # s/xxx/xxx/,匹配第一个遇到的字符串
    sed -i "s/name/nickname/" a.txt
    # 修改后的文档结果
    # nickname:jack
    # nicknamespace-name:dev-center
    # nick-nickname:tom
    
    # s/xxx/xxx/g,匹配所有遇到的字符串
    sed -i "s/name/nickname/g" a.txt
    # 修改的文档结果
    # nickname:jack
    # nicknamespace-nickname:dev-center
    # nick-nickname:tom
    
    # s/^xxx/xxx/g,只匹配xxx开头的
    sed -i "s/^name/nickname/g" a.txt
    # 修改后的文档输出结果
    # nickname:jack
    # nicknamespace-name:dev-center
    # nick-name:tom
    
    # 将namespace-name:dev-center换成namespace-name:uat-center
    sed -i "s/^namespace-name.*/namespace-name:uat-center/g" a.txt
    
    # 如果匹配或者需要替换的字符串中,出现与分隔符一致的符号则会报错,需要换乘其他分隔符,如 #等
    echo "http://www.baidu.com" >> a.txt | sed -i "s#http:.*#http://www.qq.com#g" a.txt
    

    tee 读取将标准输入内容并将内容输入到文件

    tee -a a.txt <<EOFaaabbbcccEOF
    

    压缩解压

    # 1 tar
    # 1.1 tar压缩
    tar -zcvf apps.tar.gz /apps
    
    # 1.2 tar 解压 -C 后跟需要解压到什么位置, 忽略-C 则解压到当前文件
    tar -zxvf apps.tar.gz -C /opt
    
    # zip解压,解压window上传的zip包
    unzip apps.zip
    

    expect 自动交互套件

    写脚本中经常需要自动处理一些交互的内容,比如自动登录等,需要有expect套件,yum -y install expect安装

    # 添加用户的操作
    USERNAME="admin"
    PASSWORD="123456"
    expect << EOF
            # 执行超时时间
            set timeout 5
            # spawn后面跟需要执行的命令
            spawn useradd $USERNAME
            expect "#"
            set timeout 10
            spawn passwd $USERNAME
            expect {
                    # 遇到New password:输入密码并回车
                    "New password:" {send "$PASSWORD\r"; exp_continue}
                    # 遇到Retype new password再次输入密码时,自动输入密码并回车
                    "Retype new password" {send "$PASSWORD\r"}
            } 
           expect eof
    EOF
    

    例子2:

    #!/usr/bin/expect -f
    # 需求:将脚本发送到远程服务器并执行的操作
    set serverIp [lindex $argv 0]
    set password [lindex $argv 1]
    set file_name [lindex $argv 2]
    set local_path [lindex $argv 3]
    set remote_path [lindex $argv 4]
    
    # 发送脚本到远程服务器
    set timeout 15
    send "scp -r $local_path/$file_name $serverIp:$remote_path\r"
    expect {
            "password:" {send "$password\r"; exp_continue}
            "(yes/no)?" {send "yes\r"; exp_continue}
    }
    expect "#"
    expect eof
    
    # 登陆远程服务器
    set timeout 10
    spawn ssh [lindex $serverIp]expect {
            "password:" {send "$password\r"; exp_continue}
            "(yes/no)?" {send "yes\r"; exp_continue}
    }
    expect "#"
    
    # 切换到具体目录并执行脚本
    send "cd $remote_path\r"
    expect "#"
    set timeout 60
    send "./$file_name\r"
    expect "#"
    expect eof
    

    设置集群机器间免密登陆

    # 其中一台绵密登陆其他机器的设置, 需要都能互相免密for循环每台机都执行一遍即可
    server_name="admin"
    server_password="123456"
    nodes=("192.168.0.0" "192.168.0.2" "192.168.0.3")
    if [ ! -f ~/.ssh/id_rsa ];then
            ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsaelse 
           echo "id_rsa hs created ..."
    fi
    
    for (( i=0;i<${#nodes[@]}; i++ )); do
            server_ip=${nodes[$i]}
            echo "ssh-copy-id $server_name@$server_ip"
            expect << EOF
                    set timeout 30
                    spawn ssh-copy-id $server_name@$server_ip
                    expect {
                            "yes/no" { send "yes\n";exp_continue }
                            "password" { send "$server_password\n" }
                    }
                    expect "#"
                    expect eof
            EOF
    done
    

    vim 全局替换字符串

    # 将tomcat替换成jetty的例子(在底行模式执行)
    %s/tomcat/jetty
    

    相关文章

      网友评论

        本文标题:SHELL 笔记

        本文链接:https://www.haomeiwen.com/subject/htokwltx.html