hunkier

学习笔记,开源代码,技术分享

常用的Shell脚本和Linux命令

收集工作中经常用的Linux命令和shell脚本

zip 压缩和解压缩
# 压缩文件夹
zip -r data.zip  data
# 解压缩文件,默认解压到当前路径
unzip data.zip
# 解压到指定路径
unzip data.zip -d destDir
# 查看帮助
unzip -h
tar 压缩和解压缩
# 压缩文件夹
tar -czf data.tar.gz data
# 解压缩到当前路径
tar -xzf data.tar.gz -C /destDir
tail查看和过滤日志文件
# 动态输出Tomcat日志到控制台
tail -1000f catalina.out
# 按字段过滤日志
tail -1000f catalina.out | grap -A 20 'ERROR'
netstat 查看监听端口的进程
# 查看监听端口为1600的进程
netstat -tlpn | grep "\b16000\b"
kill停止指定进程
# 停止当前路径下的应用进程
kill -9 $(ps -ef|grep $(pwd)|grep -v grep|awk '{print $2}')
# 停止监听端口为1600的进程
kill -9 $(netstat -tlpn | grep "\b16000\b" | awk '{print $7}' | cut -d '/' -f 1)
sed替换文件内容
# 替换Tomcat默认端口
sed -i "s|<Connector port=\"8080\"|<Connector port=\"51000\"|g" server.xml && \
sed -i "s|<Connector port=\"8009\"|<Connector port=\"51080\"|g" server.xml
shell 判断文件夹或文件是否存在

文件夹不存在则创建

if [ ! -d "/data/" ];then
mkdir /data
else
echo "文件夹已经存在"
fi

文件存在则删除

if [ ! -f "/data/filename" ];then
echo "文件不存在"
else
rm -f /data/filename
fi

判断文件夹是否存在

if [ -d "/data/" ];then
echo "文件夹存在"
else
echo "文件夹不存在"
fi

判断文件是否存在

if [ -f "/data/filename" ];then
echo "文件存在"
else
echo "文件不存在"
fi

文件比较符

-e 判断对象是否存在
-d 判断对象是否存在,并且为目录
-f 判断对象是否存在,并且为常规文件
-L 判断对象是否存在,并且为符号链接
-h 判断对象是否存在,并且为软链接
-s 判断对象是否存在,并且长度不为0
-r 判断对象是否存在,并且可读
-w 判断对象是否存在,并且可写
-x 判断对象是否存在,并且可执行
-O 判断对象是否存在,并且属于当前用户
-G 判断对象是否存在,并且属于当前用户组
-nt 判断file1是否比file2新  [ "/data/file1" -nt "/data/file2" ]
-ot 判断file1是否比file2旧  [ "/data/file1" -ot "/data/file2" ]
判断某个变量是否包含字符串/变量的方法

尝试了有3种方法:

  1. 使用“=~”符号,注意前后必须要有空格!

可以输出正确结果,被匹配的字符串必须要有引号括起来!

➜  ~ a1='hello.world'
➜  ~ a2='helloworld'
➜  ~ b='.'
➜  ~ if [[ ${a1} =~ '.' ]];then echo "yes";else echo "no";fi
yes
➜  ~ if [[ ${a2} =~ '.' ]];then echo "yes";else echo "no";fi
yes
➜  ~ if [[ ${a1} =~ "." ]];then echo "yes";else echo "no";fi
yes
➜  ~ if [[ ${a2} =~ "." ]];then echo "yes";else echo "no";fi
yes
➜  ~ if [[ ${a1} =~ "${b}" ]];then echo "yes";else echo "no";fi
yes
➜  ~ if [[ ${a2} =~ "${b}" ]];then echo "yes";else echo "no";fi
yes
➜  ~ 

不能输出正确结果

➜  ~  a1='hello.world'
➜  ~ '
➜  ~  b='.'
➜  ~  if [[ ${a1} =~ . ]];then echo "yes";else echo "no";fi
yes
➜  ~  if [[ ${a2} =~ . ]];then echo "yes";else echo "no";fi
yes
➜  ~  if [[ ${a1} =~ ${b} ]];then echo "yes";else echo "no";fi
yes
➜  ~  if [[ ${a2} =~ ${b} ]];then echo "yes";else echo "no";fi
yes
➜  ~  if [[ ${a1} =~ '${b}' ]];then echo "yes";else echo "no";fi
no
➜  ~  if [[ ${a2} =~ '${b}' ]];then echo "yes";else echo "no";fi
no
  1. 使用”==“加通配符wildcard,注意等号前后必须有空格,注意,通配符跟正则表达式有所区别,*表示匹配 0 或多个字符

可以输出正确结果

➜  ~  a1='hello.world'
➜  ~  a2='helloworld'
➜  ~  if [[ ${a1} == *.* ]];then echo "yes";else echo "no";fi
yes
➜  ~  if [[ ${a2} == *.* ]];then echo "yes";else echo "no";fi
no

不能输出正确结果 ,通配符不能用括号括起来!

➜  ~  a1='hello.world'
➜  ~  a2='helloworld'
➜  ~  if [[ ${a2} == "*.*" ]];then echo "yes";else echo "no";fi
no
➜  ~  if [[ ${a1} == "*.*" ]];then echo "yes";else echo "no";fi
no
➜  ~  if [[ ${a1} == '*.*' ]];then echo "yes";else echo "no";fi
no
➜  ~  if [[ ${a2} == '*.*' ]];then echo "yes";else echo "no";fi
no
  1. 使用echo + grep -q 选项

使用这种方法时匹配是否有”.”会不正常,所以我们换成匹配普通字符,有没有括号都可以

➜  ~  a1='hello.world'
➜  ~  a2='helloworld'
➜  ~  a3="helloworlda"
➜  ~  if ( echo ${a1} |grep -q a );then echo "yes";else echo "no";fi
no
➜  ~  if ( echo ${a2} |grep -q a );then echo "yes";else echo "no";fi
no
➜  ~  if ( echo ${a3} |grep -q a );then echo "yes";else echo "no";fi
yes
➜  ~  if ( echo ${a1} |grep -q 'a' );then echo "yes";else echo "no";fi
no
➜  ~  if ( echo ${a2} |grep -q 'a' );then echo "yes";else echo "no";fi
no
➜  ~  if ( echo ${a3} |grep -q 'a' );then echo "yes";else echo "no";fi
yes
➜  ~  if ( echo ${a1} |grep -q "a" );then echo "yes";else echo "no";fi
no
➜  ~  if ( echo ${a2} |grep -q "a" );then echo "yes";else echo "no";fi
no
➜  ~  if ( echo ${a3} |grep -q "a" );then echo "yes";else echo "no";fi
yes
crontab定时任务
crontab -e
# 每分钟执行一次monitor.sh脚步
*/1 * * * * /usr/java/monitor.sh
# 数据库备份
0 3 * * *  /bin/sh /data1/script/databak.sh &
0 4 * * * find /data1/databak -type f -mtime +3 -exec rm {} \;
databak.sh内容
#!/bin/bash
/usr/bin/mysqldump -uroot -p123456 test >/data1/databak/`date +%Y%m%d`test.sql 2>/dev/null
监控Tomcat是否正常启动

#!/bin/sh
# 定义环境变量(要改成自己的jdk相关地址)
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_191-oraclejdk
export CLASSPATH=$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin
TomcatHome=/opt/webserver/pf-platform

#获取tomcat进程ID(这里注意tomcat7要改成自己的tomcat目录名)
TomcatID=$(ps -ef |grep tomcat |grep -w $TomcatHome|grep -v 'grep'|awk '{print $2}')

#tomcat启动程序(这里注意要改成自己tomcat实际安装的路径)

StartTomcat=$TomcatHome/bin/startup.sh
TomcatCache=$TomcatHome/work

#自己定义要监控的页面地址,页面越简单越好,比如:页面上写个success即可
WebUrl=http://172.20.8.5:41000/pf-platform/login/login

#日志输出 (自己定义地址,用于输出监控日志和监控报错日志)
#TomcatMonitorLog=$TomcatHome/TomcatMonitor-$(date '+%Y%m%d%H%M%S').log
TomcatMonitorLog=$TomcatHome/logs/TomcatMonitor-$(date '+%Y-%m-%d').log
GetPageInfo=$TomcatHome/logs/PageInfo-$(date '+%Y-%m-%d').log
if [ ! -d $TomcatHome/logs ]; then mkdir -p $TomcatHome/logs ; fi
Monitor()
{
echo "[info]开始监控tomcat...[$(date +'%F %H:%M:%S')]"
if [[ $TomcatID ]];then # 这里判断TOMCAT进程是否存在
                echo "[info]当前tomcat进程ID为:$TomcatID,继续检测页面..."
                # 检测是否启动成功(成功的话页面会返回状态"302")
                TomcatServiceCode=$(curl -s -o $GetPageInfo -m 10 --connect-timeout 10 $WebUrl -w %{http_code})
                if [ $TomcatServiceCode -eq 302 ];then
                                echo "[info]页面返回码为$TomcatServiceCode,tomcat启动成功,测试页面正常......"
                        else
                                echo "[error]tomcat页面出错,请注意......状态码为$TomcatServiceCode,错误日志已输出到$GetPageInfo"
                                echo "[error]页面访问出错,开始重启tomcat"
                                kill -9 $TomcatID # 杀掉原tomcat进程
                                sleep 3
                                #rm -rf $TomcatCache # 清理tomcat缓存
                                $StartTomcat
                fi
        else
                echo "[error]tomcat进程不存在!tomcat开始自动重启..."
                echo "[info]$StartTomcat,请稍候......"
                #rm -rf $TomcatCache
                $StartTomcat
fi
echo "------------------------------"
}

Monitor>>$TomcatMonitorLog
监控netty服务是否正常开启端口
#!/bin/sh
# 定义环境变量(要改成自己的jdk相关地址)
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_191-oraclejdk
export CLASSPATH=$JAVA_HOME/lib:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin
NettyServerHome=/opt/webserver/mtech-cloud-netty-server

#获取netty-server进程ID(这里注意netty-server7要改成自己的netty-server目录名)
NettyServerID=$(ps -ef |grep netty-server |grep -w $NettyServerHome |grep -w java |grep -v 'grep'|awk '{print $2}')

#netty-server启动程序(这里注意要改成自己netty-server实际安装的路径)
StartNettyServer=$NettyServerHome/bin/start.sh

#netty监听端口
NettyPort=16000

#日志输出 (自己定义地址,用于输出监控日志和监控报错日志)
NettyServerMonitorLog=$NettyServerHome/logs/NettyServerMonitor-$(date +'%F').log
GetPageInfo=$NettyServerHome/logs/PortInfo-$(date +'%F').log
if [ ! -d $NettyServerHome/logs ]; then mkdir -p $NettyServerHome/logs ; fi
Monitor()
{
echo "[info]开始监控netty-server...[$(date +'%F %H:%M:%S')]"
if [[ $NettyServerID ]];then # 这里判断netty-server进程是否存在
    
        echo "[info]当前netty-server进程ID为:$NettyServerID,继续检测端口..."
        # 检测是否启动成功(成功的话会返回端口信息)
        NettyServerPort=$(checkPort $NettyPort)
        echo "端口检测结果:$NettyServerPort "
        if [ $NettyServerPort -eq 0 ];then
                echo "[info]返回码为$NettyServerPort,netty-server启动成功,测试端口正常......"
            else
                echo "[error]netty-server启动出错,请注意......, 错误日志已输出到$GetPageInfo"
                echo "[error]端口$NettyPort检测出错,开始重启netty-server"
                kill -9 $NettyServerID # 杀掉原netty-server进程
                sleep 3
                #rm -rf $netty-serverCache # 清理netty-server缓存
                $StartNettyServer  >> $NettyServerHome/logs/nohub.out & >> /dev/null
        fi
    else
        echo "[error]netty-server进程不存在!netty-server开始自动重启..."
        echo "[info]$StartNettyServer,请稍候......"
        #rm -rf $netty-serverCache
        # $StartNettyServer  >> /dev/null &
        $StartNettyServer  >> $NettyServerHome/logs/nohub.out & >> /dev/null
fi
echo "------------------------------"
}
checkPort() {
        echo "------------------------------" >> $GetPageInfo
        echo "$(date +'%F %H:%M:%S')  " >> $GetPageInfo
        echo $(netstat -tlpn | grep "\b$1\b") >> $GetPageInfo
        netstat -tlpn | grep "\b$1\b" | awk '{print $2}'
}
Monitor>>$NettyServerMonitorLog &
部署war包到tomcat
➜  web cat start.sh 
WORKDIR=/data1/webserver/mt_chs/web
cd $WORKDIR
kill -9 $(netstat -tlpn | grep "\b18080\b" | awk '{print $7}' | cut -d '/' -f 1)
echo '' > $WORKDIR/logs/catalina.out 
$WORKDIR/bin/startup.sh 

➜  web cat tailf.sh 
WORKDIR=/data1/webserver/mt_chs/web
tail -f $WORKDIR/logs/catalina.out

➜  web cat stop.sh 
WORKDIR=/data1/webserver/mt_chs/web
cd $WORKDIR
kill -9 $(netstat -tlpn | grep "\b18080\b" | awk '{print $7}' | cut -d '/' -f 1)

➜  ~ cat deploy_web.sh 
WEB_DIR=/data1/webserver/mt_chs/web
APP_DIR=$WEB_DIR/webapps/chs_web
HOME_DIR=/home/ledmon
WAR_FILE=$HOME_DIR/$1


function deploy(){
    echo "停止tomcat..."
    $WEB_DIR/stop.sh
    mkdir -p $APP_DIR
    echo "更新应用..."
    rm -rf $APP_DIR/*
    unzip $WAR_FILE -d $APP_DIR >> /dev/null
    echo "启动tomcat..."
    $WEB_DIR/start.sh
    echo "查看启动日志"
    $WEB_DIR/tailf.sh
}

if [ ! -f "$WAR_FILE" ];then
    echo "文件不存在,路径: $WAR_FILE"
elif (! echo ${WAR_FILE} |grep -q ".war" );then
    echo "文件不合法,路径:$WAR_FILE"
    echo "请选择war文件"
elif (! echo ${WAR_FILE} |grep -q "web_product" );then
    echo "文件不合法,路径:$WAR_FILE"
    echo "请选择web_proeuct*.war文件"
else
    deploy
fi
部署springboot的jar包应用
➜  appint cat start.sh 
WORKDIR=/data1/webserver/mt_chs/appint
cd $WORKDIR
kill -9 $(netstat -tlpn | grep "\b18083\b" | awk '{print $7}' | cut -d '/' -f 1)
echo '' > $WORKDIR/out.log
nohup java -jar $WORKDIR/appint_*.jar > $WORKDIR/out.log & 

➜  appint cat tailf.sh 
WORKDIR=/data1/webserver/mt_chs/appint
tail -f $WORKDIR/out.log


➜  ~ cat deploy_appint.sh 
APP_DIR=/data1/webserver/mt_chs/appint
HOME_DIR=/home/ledmon
JAR_FILE=$HOME_DIR/$1



function deploy(){
    echo "停止应用..."
    kill -9 $(netstat -tlpn | grep "\b18083\b" | awk '{print $7}' | cut -d '/' -f 1)
    mkdir -p $APP_DIR
    echo "更新应用..."
    rm -rf $APP_DIR/*.jar
    cp $JAR_FILE $APP_DIR
    echo "启动应用..."
    $APP_DIR/start.sh
    echo "查看启动日志"
    $APP_DIR/tailf.sh
}

if [ ! -f "$JAR_FILE" ];then
    echo "文件不存在,路径: $JAR_FILE"
elif (! echo ${JAR_FILE} |grep -q ".jar" );then
    echo "文件不合法,路径:$JAR_FILE"
    echo "请选择*.jar文件"
elif (! echo ${JAR_FILE} |grep -q "appint_product" );then
    echo "文件不合法,路径:$JAR_FILE"
    echo "请选择appint_product*.jar文件"
else
    deploy
fi
谢谢你请我喝牛奶

欢迎关注我的其它发布渠道