bash脚本的调试

在shebang最后一行加入-x, 这样每执行一行命令都会把执行的语句打印出来。例如:

#!/usr/bin/env bash -x

backup_file() {
    if [[ -f $1 ]] # 1. check if its a file and it does exists
    then
        # basename 将前面的路径都剔除,只保留文件名
        # $$表示pid(正在运行当前脚本的进程id)。在这里使用这个,为了防止同一天多次备份时,前面的备份被覆盖。
        local BACK="/tmp/$(basename ${1})-$(date +%F)-$$"
        echo ${BACK}
        cp $1 ${BACK}
    else
        # The file not exists
        return 1
    fi
}

backup_file /etc/hosts

if [[ $? -eq 0 ]]
then
    echo "Backup succeeded"
else
    echo "Backup failed!"
    exit 1
fi

执行结果如下:

[@bogon:bashlearn (master)]$ ./2.sh 
+ backup_file /etc/hosts
+ [[ -f /etc/hosts ]]
++ basename /etc/hosts
++ date +%F
+ local BACK=/tmp/hosts-2019-06-02-35242
+ echo /tmp/hosts-2019-06-02-35242
/tmp/hosts-2019-06-02-35242
+ cp /etc/hosts /tmp/hosts-2019-06-02-35242
+ [[ 0 -eq 0 ]]
+ echo 'Backup succeeded'
Backup succeeded


第二种写法可以使用set -x (set +x 表示停止debugging)

这样可以在脚本的任何位置控制调试的开启和关闭。

#!/usr/bin/env bash


backup_file() {
    if [[ -f $1 ]] # 1. check if its a file and it does exists
    then
        # basename 将前面的路径都剔除,只保留文件名
        # $$表示pid(正在运行当前脚本的进程id)。在这里使用这个,为了防止同一天多次备份时,前面的备份被覆盖。
        local BACK="/tmp/$(basename ${1})-$(date +%F)-$$"
        echo ${BACK}
        cp $1 ${BACK}
    else
        # The file not exists
        return 1
    fi
}

set -x # 在此处开启调试
backup_file /etc/hosts
set +x # 在此处关闭调试,后面部分不会输出调试语句

if [[ $? -eq 0 ]]
then
    echo "Backup succeeded"
else
    echo "Backup failed!"
    exit 1
fi

-e参数

e = exit

一旦执行到错误的地方就退出。

和-x一起使用,可以精确的定位脚本哪一行出的错(因为出错就会退出)

#!/bin/bash -ex
#!/bin/bash -xe
#!/bin/bash -x -e
#!/bin/bash -e -x

例如:

#!/usr/bin/env bash -ex

FILE_NAME="/not/here"
ls ${FILE_NAME}
echo ${FILE_NAME}

由于文件不存在,执行结果如下:

[@bogon:bashlearn (master)]$ ./4.sh 
+ FILE_NAME=/not/here
+ ls /not/here
ls: /not/here: No such file or directory