bash - bash 脚本的奇怪行为
问题描述
我有 2 个脚本。
script.conf
#!/bin/bash
set -o errexit
set -o nounset
set -o pipefail
# set -o xtrace
[ -f $HOME/Templates/bash_colors.sh ] && source $HOME/Templates/bash_colors.sh
INFO=${INFO:-"1"}
DEBUG=${DEBUG:-"0"}
ERROR=${ERROR:-"1"}
Red=${Red:-}
Yellow=${Yellow:-}
Cyan=${Cyan:-}
Color_Off=${Color_Off:-}
__msg_error() {
[[ "${ERROR}" == "1" ]] && echo -e "${Red}[ERROR]: $*${Color_Off}";
}
__msg_debug() {
[[ "${DEBUG}" == "1" ]] && echo -e "${Yellow}[DEBUG]: $*${Color_Off}";
}
__msg_info() {
[[ "${INFO}" == "1" ]] && echo -e "${Cyan}[INFO]: $*${Color_Off}";
}
和testConf.sh
#!/bin/bash
# INFO="0"
scriptDir="${BASH_SOURCE%/*}"
[ -f ${scriptDir}/script.conf ] && source ${scriptDir}/script.conf
INFO="0"
__msg_error "Test error1"
__msg_info "Test Info"
__msg_error "Test error2"
__msg_debug "Test debug"
奇怪的是,如果设置INFO
为 0,我希望这两个错误消息都会被回显,但事实并非如此。只打印第一个。我不明白为什么。也许你有一个想法?
似乎脚本在INFO
为 0 时停止。
查看跟踪:
++ INFO=1
++ DEBUG=0
++ ERROR=1
++ Red='\033[0;31m'
++ Yellow='\033[0;33m'
++ Cyan='\033[0;36m'
++ Color_Off='\033[0m'
+ INFO=0
+ __msg_error 'Test error1'
+ [[ 1 == \1 ]]
+ echo -e '\033[0;31m[ERROR]: Test error1\033[0m'
[ERROR]: Test error1
+ __msg_info 'Test Info'
+ [[ 0 == \1 ]]
但为什么?
bash_colors.sh
#!/bin/bash
# src: https://stackoverflow.com/a/28938235/1959528
# Reset
Color_Off='\033[0m' # Text Reset
# Regular Colors
Black='\033[0;30m' # Black
Red='\033[0;31m' # Red
Green='\033[0;32m' # Green
Yellow='\033[0;33m' # Yellow
Blue='\033[0;34m' # Blue
Purple='\033[0;35m' # Purple
Cyan='\033[0;36m' # Cyan
White='\033[0;37m' # White
# Bold
BBlack='\033[1;30m' # Black
BRed='\033[1;31m' # Red
BGreen='\033[1;32m' # Green
BYellow='\033[1;33m' # Yellow
BBlue='\033[1;34m' # Blue
BPurple='\033[1;35m' # Purple
BCyan='\033[1;36m' # Cyan
BWhite='\033[1;37m' # White
# Underline
UBlack='\033[4;30m' # Black
URed='\033[4;31m' # Red
UGreen='\033[4;32m' # Green
UYellow='\033[4;33m' # Yellow
UBlue='\033[4;34m' # Blue
UPurple='\033[4;35m' # Purple
UCyan='\033[4;36m' # Cyan
UWhite='\033[4;37m' # White
# Background
On_Black='\033[40m' # Black
On_Red='\033[41m' # Red
On_Green='\033[42m' # Green
On_Yellow='\033[43m' # Yellow
On_Blue='\033[44m' # Blue
On_Purple='\033[45m' # Purple
On_Cyan='\033[46m' # Cyan
On_White='\033[47m' # White
# High Intensity
IBlack='\033[0;90m' # Black
IRed='\033[0;91m' # Red
IGreen='\033[0;92m' # Green
IYellow='\033[0;93m' # Yellow
IBlue='\033[0;94m' # Blue
IPurple='\033[0;95m' # Purple
ICyan='\033[0;96m' # Cyan
IWhite='\033[0;97m' # White
# Bold High Intensity
BIBlack='\033[1;90m' # Black
BIRed='\033[1;91m' # Red
BIGreen='\033[1;92m' # Green
BIYellow='\033[1;93m' # Yellow
BIBlue='\033[1;94m' # Blue
BIPurple='\033[1;95m' # Purple
BICyan='\033[1;96m' # Cyan
BIWhite='\033[1;97m' # White
# High Intensity backgrounds
On_IBlack='\033[0;100m' # Black
On_IRed='\033[0;101m' # Red
On_IGreen='\033[0;102m' # Green
On_IYellow='\033[0;103m' # Yellow
On_IBlue='\033[0;104m' # Blue
On_IPurple='\033[0;105m' # Purple
On_ICyan='\033[0;106m' # Cyan
On_IWhite='\033[0;107m' # White
解决方案
你的代码正在做你告诉它做的事情。在scipt.conf
你设置一些标志,特别是errexit
标志并初始化你的错误、调试和信息标志:
INFO=${INFO:-"1"}
DEBUG=${DEBUG:-"0"}
ERROR=${ERROR:-"1"}
然后创建使用标志的函数:
__msg_error() {
[[ "${ERROR}" == "1" ]] && echo -e "${Red}[ERROR]: $*${Color_Off}";
}
__msg_debug() {
[[ "${DEBUG}" == "1" ]] && echo -e "${Yellow}[DEBUG]: $*${Color_Off}";
}
__msg_info() {
[[ "${INFO}" == "1" ]] && echo -e "${Cyan}[INFO]: $*${Color_Off}";
}
(注意:您的ERROR
和INFO
标志设置为1
)
然后在testConf.sh
你设置INFO
为zero
所以将输出的唯一消息是ERROR=1
INFO="0"
__msg_error "Test error1"
__msg_info "Test Info"
__msg_error "Test error2"
__msg_debug "Test debug"
运行脚本会给出预期的输出,"Test error1"
并且"Test error2"
显示得很好而且很红,例如
$ bash ./testConf.sh
[ERROR]: Test error1
[ERROR]: Test error2
注意:但是必须"./"
在文件名之前提供,否则会发生我在第一条评论中讨论的条件,(您连接两个文件名,因为从 $PWD 运行时将没有路径信息而不会"./"
导致测试和源失败.
当您抱怨只显示一个输出时,这set -o errexit
会导致整个脚本在第一个错误时退出。如果您想遵循已完成的操作,只需在脚本中添加set -x
为第一行。#!/bin/bash
您会发现由于比较'Test Info'
失败而触发了退出,然后退出跳过输出[[ 0 == \1 ]]
是正常行为。Test error2
在conf.script
中,我建议在尝试获取源之前验证要获取的文件的存在和非空性质,并检查源是否完成且没有错误,例如
colorfile="$HOME/tmpd/bash_colors.sh"
if [ ! -s "$colorfile" ]; then
printf "error: file not found or empty '%s'\n" "$colorfile" >&2
else
. "$colorfile" || {
printf "error: failed to source '%s'\n" "$colorfile" >&2
}
fi
(注意:您可以使用'.'
将文件来源到当前。'.'
是原始来源运算符,但后来source
也添加了别名。
如果您在其他地方遇到问题,请告诉我。它可能是一个杂散字符,例如卡在文件中的回车符,当我复制片段时未复制它。
推荐阅读
- python - 使用 Seaborn 的 factorplot 方法时遇到问题
- vim - 无法从 vimrc (mac) 成功使用自定义映射的 vim 命令
- sql - 如果运行超过 20 分钟,Postgresql 将终止查询
- javascript - 用于绘制图像的 for 循环
- express - 如果我将所有内容都包含在 jwt 有效负载中,是否需要在数据库中查找用户?
- salesforce - 在 SalesForce 中构建报告/仪表板
- android - 如何在 Google Maps Android 上“增加” VisibleRegion 的大小
- r - 如何在 R 中读取带有初始标签的 XML 文件
- python - 如何修复我的 pandas 数据框中的索引以不将值仅保持为零,并增加值?
- python - 如何将列表列表拆分为字典键/值对?