我有一个 bash 脚本
initial-tests.bash
,它使用另一个具有纯函数的脚本来运行一些测试。它看起来像:
#! /bin/bash
source ./scripts/_functions.bash
check=$(do_check)
echo "$check"
脚本
_functions.bash
包含以下内容:
#! /bin/bash
# Here we save reusable functions to aid the other scripts
echoerr() {
# Output to stderr while freeing stdout for returns
echo -ne $red
echo "ERROR: $*" | ts '[%Y-%m-%d %H:%M:%S]' 1>&2
echo -ne $nc
}
first_check() {
echoerr "This is an echoerr with echo -e"
echo false
}
do_check() {
local x
x=$(first_check)
if [[ "$x" = 'false' ]]; then
echo
else
echo false
fi
}
initial-tests.bash
又由另一个脚本提供 main.bash
:
#! /bin/bash
nc='\e[0m'
yellow='\e[1;33m'
green='\e[1;32m'
red='\e[1;31m'
blue='\e[1;34m'
# Fail early in case of argumentation error
echo -e "${blue}- - - Initial Checks - - -${nc}"
source ./scripts/initial-checks-load-config.bash
当我直接
source
该脚本时,测试的输出是正确的:source scripts/initial-tests.bash
:
[2024-10-10 08:30:55] ERROR: This is an echoerr with echo -e
但是当我运行
bash main.bash
时,测试是错误的:
- - - Initial Checks - - -
[2024-10-10 08:30:49] ERROR: This is an echoerr with echo -e
false
请注意,
false
应为空。
我不清楚为什么
source
会产生与 bash
运行不同的结果。
更多信息:
看来我的问题是:
initial-tests.bash
传递到 main.bash
,它们是颜色转义序列echo -ne $nc
作为 echoerr
中的最后一个命令,将 $nc
添加到 echo
函数中紧随其后的空白 first_check
之前。关于第 1 点,当我运行
bash main.bash
然后运行 source initial-tests.bash
时,源脚本将可以访问颜色转义序列。但是当我直接 source initial-tests.bash
时,由于颜色序列没有(重新)定义在其中,所以这些颜色序列是空白的。
关于第 2 点,使用
-n
前置到下一个 echo:
# echo -n hi; echo bye
hibye
当
$nc
由于直接获取 initial-tests.bash
而为空时,函数 first_check
只会产生一个 false,因为没有任何内容被添加到“false”之前,因为 $nc 为空:
echo -ne $nc (last command in echoerr)
echo false
do_check
中的 if 测试通过:
if [[ "$x" = 'false' ]]; then
echo
else
echo false
fi
=> 所以输出是 ''。
但是,当我运行
bash main.bach
时,$nc
包含一个颜色转义序列,因此该序列被前置到 false 并使相同的测试失败,因此转到 else,并回显“false”而不是空= > 所以输出是“假”。由于前置值是转义序列,因此检测起来很棘手。
我可以通过以下方式解决这个问题:
initial-tests.bash
echo -n
中删除 echoerr
以避免在紧邻的下一个回声之前添加任何内容。