首页 > 技术文章 > Linux Shell脚本

ruhuanxingyun 2021-01-02 10:53 原文

一、Shell语法

  1. 运行方式

    A. 作为可执行文件:脚本保存到文件中(如:web-admin.sh),并切换到当前文件目录,赋予脚本执行权限chmod +x ./web-admin.sh,执行脚本./web-admin.sh;

      附:linux下.表示当前目录,..表示父目录,./表示当前目录的全路径,如果运行某个可执行文件可用cd /usr/local/nginx/sbin && ./nginx或者绝对路径/usr/local/nginx/sbin/nginx;

    B. 作为解释器参数:/bin/sh web-admin.sh,这种在脚本里第一行指定解释器信息会忽略。

  2. 变量

    A. 变量定义不能使用$符号,使用变量是在变量名前加$符号,最好带上花括号,有助于解释器识别变量的边界;

    B. 变量名和等号之间不能有空格;

    C. 完整的表达式要被反引号 ` ` 包含;

    D. 双引号里可以有变量,还可以出现转义字符,但是单引号里变量是无效的,因为任何字符都会原样输出。

  3. 参数传递

    A. 执行Shell脚本时,可向脚本传递参数,脚本内获取参数的格式为:$n,n代表数字,从1开始,1表示第一个参数,注意$0表示执行的文件绝对路径名。

  4. 命令

    A. echo:用于向窗口输出字符串文本;

    B. printf:格式化输出文本;

    C. test:检查条件是否成立。

  5. 输入/输出重定向

    A. n >> file:将文件描述符为n的文件以追加的方式重定向到file;

    B. n >& m:将输出文件m和n合并。 

  6. if else流程控制

    A. if中括号前后一定要加空格;

    B. -d:判断目录是否存在;

      -f:判断常规文件是否存在。

# 如果文件夹不存在,创建文件夹
if [ ! -d "/myfolder" ]; then
  mkdir /myfolder
fi

   7. for循环语句

for var in item1 item2 ... itemN 
do
command1
command2
...
commandN
done

   8. 特殊符号

    A. $n 脚本的第n个参数值,n=1..9;

    B. $? 执行上一个指令的返回值 (显示最后命令的退出状态,0表示没有错误,其他任何值表明有错误);

 

二、常见错误

  1. 错误一:shell脚本执行结果报$'\r': 未找到命令;

    原因:脚本是使用VS Code编辑器编写的,查找是换行符的问题,注意是LF,而不是CRLF。

   2. 错误二:/bin/bash^M: bad interpreter: No such file or directory

    原因:脚本是使用Notepad++编辑器编写的,查找还是换行符的问题,注意是Unix,不是Windows。

 

三、使用举例

  1. 检测网络是否ping通

# 在内网下,DNS不能配置公网,否则Docker服务因为DNS解析巨慢
ping -c1 www.baidu.com
if [ $? -ne 0 ];then
    echo "当前环境判断为隔离内网环境"
    sed -ri '/(114.114.114.114|8.8.)/d' /etc/resolv.conf
    echo -e "#nameserver 114.114.114.114\n#nameserver 8.8.8.8" >> /etc/resolv.conf
else
    echo "当前环境判断为可访问公网环境"
fi

  2. Jenkins SpringBoot jar包启动脚本:sh web-admin.sh

#!/bin/bash
PROJECT_PACKAGE=web-admin-0.0.1-SNAPSHOT.jar
PATH_NAME=test/web-admin/web-admin
# 删除文件
rm -rf /project/web/jar/$PROJECT_PACKAGE
# 拷贝文件
cp /var/lib/jenkins/workspace/$PATH_NAME/target/$PROJECT_PACKAGE /project/web/jar/
# 切换路径
cd /project/web/jar/

pid=`ps -ef | grep $PROJECT_PACKAGE | grep -v grep | awk '{print $2}'`
if [ -n "$pid" ]
then
   # 杀死存在进程
   kill -9 $pid
fi

# 避免项目启动之后被Jenkins杀掉
BUILD_ID=dontKillMe
# 执行
nohup java -jar $PROJECT_PACKAGE --spring.profiles.active=test >> /project/web/log/web-admin.log 2>&1 &
# echo 命令用于向窗口输出文本
echo "web-admin项目启动成功!"

   3. MySQL全量备份脚本:定时任务生效就行

#!/bin/bash
# mysqldump的路径
DUMP=/usr/bin/mysqldump
# 数据库登录名
DB_USER=root
# 数据库登录密码
DB_PASSWORD=password
# 备份文件目录
BAK_DIR=/admin
# 当前时间
DATE=`date +%Y%m%d%H%M`

# 目录不存在就创建
if [ ! -d "$BAK_DIR" ]; then
    mkdir -p $BAK_DIR
fi

$DUMP -u$DB_USER -p$DB_PASSWORD --lock-all-tables --databases admin | gzip >$BAK_DIR/${DATE}.sql.gz

# 只保留一周的备份数据
find $BAK_DIR -type d -mtime +7 -name "*.sql.gz" -exec rm -rf {} \;

echo "数据库全量备份成功!"

 

推荐阅读