一、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 "数据库全量备份成功!"