Bash: 停止函数参数的变量扩展

Bash: stop variable expansion for function argument

我正在尝试编写一个具有日志记录功能的 bash 脚本:

log() {
   echo  2>&1
}

我检查了以下命令的输出:

ARCHIVE_PREFIX=  // value = myFile
ARCHIVE_FILE_PATTERN="${ARCHIVE_PREFIX}-*.zip" // looking for zip archive starting with my file
log "Searching current directory for pattern - log: $ARCHIVE_FILE_PATTERN"  
echo "Searching current directory for pattern - echo: $ARCHIVE_FILE_PATTERN"

我希望最后两行打印相同的内容,但输出结果是:

Searching current directory for pattern - log: myFile-08022022.zip // an archive from current working dir
Searching current directory for pattern - log: myFile-*.zip

谁能解释一下为什么会这样,我该如何更改逻辑以便函数使用实际变量值?

您尝试打印的变量是所有结果的数组。 你必须遍历数组来打印每个元素,就像这样

for FILE in $ARCHIVE_FILE_PATTERN
do
log "Searching current directory for pattern - log: $FILE"  
echo "Searching current directory for pattern - echo: $FILE"
done

我不确定 bash 循环的语法,但你知道如果这不起作用,你可以重写它。

正如 Biffen 所说,这是因为 log 中的 </code> 引用未被引用。这是一个重现问题的小例子:</p> <pre><code>$ ls -l total 0 -rw-r--r-- 1 igstan staff 0 Mar 9 12:55 bar.md -rw-r--r-- 1 igstan staff 0 Mar 9 12:55 foo.md $ PATTERN=*.md $ echo "$PATTERN" *.md $ echo $PATTERN bar.md foo.md

在你的情况下,没有引号,echo 将:

  1. </code>扩展为<code>myFile-*.zip,这是一个glob pattern
  2. 将 glob 模式扩展为 一个列表 与模式匹配的文件
  3. 回显列表

所以解决方法是引用它:

log() {
  echo "" 2>&1
}

此外,我认为您不想将 stderr (2) 重定向到 stdout (1),但可能相反,将 stdout 重定向到 stderr,这样就不会记录日志“正常”程序输出的一部分:

log() {
  echo "" 1>&2
}

然而,如果我们用 previously-declared PATTERN 变量测试它,我们会看到这种情况发生:

$ log "$PATTERN"
*.md
$ log $PATTERN # glob pattern is expanded before being passed to `log`
bar.md

第二种情况,只有一个文件名被打印出来。这是因为 glob 扩展为文件名的 列表 (松散地说),所以如果你真的想要灵活地打印整个结果,你必须从 </code> 到 <code>$@(函数的所有参数)在 log 函数内:

log() {
  echo "$@" 1>&2
}

我们现在有这些结果:

$ log "$PATTERN"
*.md
$ log $PATTERN # glob pattern is expanded before being passed to `log`
bar.md foo.md