Bash 函数在来源和分叉时的行为不同

问题描述 投票:0回答:1

我有一个 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
运行不同的结果。

更多信息:

  • 操作系统:Ubuntu 24.04.1 LTS(GNU/Linux 6.8.0-1015-azure x86_64)
  • Bash:GNU bash,版本 5.2.21(1)-release (x86_64-pc-linux-gnu)
linux bash shell
1个回答
0
投票

看来我的问题是:

  1. 无源变量未从
    initial-tests.bash
    传递到
    main.bash
    ,它们是颜色转义序列
  2. 使用
    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”而不是空= > 所以输出是“假”。由于前置值是转义序列,因此检测起来很棘手。

我可以通过以下方式解决这个问题:

  1. 确保颜色序列变量始终可用
    initial-tests.bash
  2. 或者从
    echo -n
    中删除
    echoerr
    以避免在紧邻的下一个回声之前添加任何内容。
© www.soinside.com 2019 - 2024. All rights reserved.