之前在写shell脚本时,每次调试脚本非常麻烦。
过程如下 写脚本—运行脚本—脚本语法有问题----找到报错的行----修改后继续运行脚本----脚本中部分代码报错还能继续运行----再次调试脚本—直到脚本正常运行。
下面介绍几个实用的小技巧
set -o nounset
1、不加nounset
[root@lineqi ~]# cat testjs.sh
#!/bin/bash
bb=“cccc”
echo $aa
echo $bb
[root@lineqi ~]# ./testjs.sh
cccc
不加nounset参数时,遇到不存在的变量,默认情况下会忽略,直接执行下行语句。
2、加nounset
#!/bin/bash
set -o nounset
bb=“cccc”
echo $aa
echo $bb
[root@lineqi ~]# ./testjs.sh
./testjs.sh: line 4: aa: unbound variable
不加nounset参数时,遇到不存在的变量,会提示错误信息,不会执行下行语句。
set -o errexit
在默认情况下,遇到shell脚本遇到执行错误时,会跳过并继续执行后命令,这时可以通过errexit来避免。
[root@lineqi ~]# /opt/install_mysql57_v1.5.sh
- v_mysql_data=/mysql/data
- v_mysql_log=/mysql/log
- v_software_dir=/opt
- v_tar_name=/opt/mysql-5.7.29-1.el7.x86_64.rpm-bundle.tar.tar
++ rpm -qa
++ grep mariadb
++ wc -l - is_mariadb_install=0
- ‘[’ 0 -ge 0 ‘]’
- echo aa
aa
++ rpm -qa
++ grep mariadb - cat
- mount /dev/cdrom /mnt
mount: /dev/sr0 is write-protected, mounting read-only
mount: /dev/sr0 is already mounted or /mnt busy
/dev/sr0 is already mounted on /mnt
说明:在mount /dev/cdrom /mnt后还有一些脚本需要执行的,这里就没有完全拷贝出来了。
bash -n /opt/install_mysql57_v1.5.sh
运行脚本前,检查语法错误
[root@lineqi ~]# bash -n /opt/install_mysql57_v1.5.sh
/opt/install_mysql57_v1.5.sh: line 19: syntax error near unexpected token fi' /opt/install_mysql57_v1.5.sh: line 19:
fi’
set -o verbose
在脚本前set -o verbose加上参数,执行过程如下
[root@lineqi ~]# /opt/install_mysql57_v1.5.sh
v_mysql_data=/mysql/data
v_mysql_log=/mysql/log
v_software_dir=/opt
v_tar_name=/opt/mysql-5.7.29-1.el7.x86_64.rpm-bundle.tar.tar
#check mariadb is installed
is_mariadb_install=rpm -qa|grep mariadb|wc -l
rpm -qa|grep mariadb|wc -l
if [ $is_mariadb_install -ge 0 ] ;
echo ‘aa’
for i in rpm -qa |grep mariadb
do
rpm -e --nodeps $i
done
fi
/opt/install_mysql57_v1.5.sh: line 18: syntax error near unexpected token fi' /opt/install_mysql57_v1.5.sh: line 18:
fi’
说明:与bash -v输出的结果基本一致,少了脚本注释和set部分
set -o xtrace
[root@lineqi ~]# /opt/install_mysql57_v1.5.sh
- v_mysql_data=/mysql/data
- v_mysql_log=/mysql/log
- v_software_dir=/opt
- v_tar_name=/opt/mysql-5.7.29-1.el7.x86_64.rpm-bundle.tar.tar
++ rpm -qa
++ grep mariadb
++ wc -l - is_mariadb_install=0
/opt/install_mysql57_v1.5.sh: line 18: syntax error near unexpected tokenfi' /opt/install_mysql57_v1.5.sh: line 18:
fi’
说明:与bash -x输出的结果基本一致
bash -x /opt/install_mysql57_v1.5.sh
跟踪脚本里每一个命令的执行过程,并附加扩充信息
[root@lineqi ~]# bash -x /opt/install_mysql57_v1.5.sh
- set -o nounset
- set -o errexit
- v_mysql_data=/mysql/data
- v_mysql_log=/mysql/log
- v_software_dir=/opt
- v_tar_name=/opt/mysql-5.7.29-1.el7.x86_64.rpm-bundle.tar.tar
++ rpm -qa
++ grep mariadb
++ wc -l - is_mariadb_install=0
/opt/install_mysql57_v1.5.sh: line 19: syntax error near unexpected token `fi’
bash -v /opt/install_mysql57_v1.5.sh
跟踪脚本里每一个命令的执行过程,并显示错误信息的行号
[root@lineqi ~]# bash -v /opt/install_mysql57_v1.5.sh
#!/bin/bash
#function :install mysql5.7 on centos7.4
#author:lineqi
#create time:2019-01-01
set -o nounset
set -o errexit
v_mysql_data=/mysql/data
v_mysql_log=/mysql/log
v_software_dir=/opt
v_tar_name=/opt/mysql-5.7.29-1.el7.x86_64.rpm-bundle.tar.tar
#check mariadb is installed
is_mariadb_install=rpm -qa|grep mariadb|wc -l
rpm -qa|grep mariadb|wc -l
if [ $is_mariadb_install -ge 0 ] ;
echo ‘aa’
for i in rpm -qa |grep mariadb
do
rpm -e --nodeps $i
done
fi
/opt/install_mysql57_v1.5.sh: line 19: syntax error near unexpected token `fi’
注意:-v参数显示已执行的脚本内容包括注释
总结:在调试shell脚本时,以上几个参数还是非常有用的。