学习空间ShellShell

SHELL 笔记

2021-09-03  本文已影响0人  FyK_21f8

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
上一篇下一篇

猜你喜欢

热点阅读