繁体   English   中英

为什么“test -f”的结果显示在终端上并包含在传递给子例程的参数中?

[英]Why are results of "test -f" displayed on the terminal and included in parameters passed to a subroutine?

我正在尝试编写一个 bash 子例程,它将像“echo”命令一样工作,除了在终端上显示文本并将它们写入日志文件。 看起来很简单,但它并没有像我认为的那样工作——它包括当前目录中的文件名。

这是带有“myecho”例程的示例脚本:

    01 #!/bin/bash
    02 logfile="/tmp/testif.log"
    03
    04 myecho () {
    05   echo $*;
    06   echo $* >>$logfile;
    07   }
    08
    09 src="/tmp/testdir"
    10 FILE=$src'/afile'
    11
    12 if test -f "$FILE"; then
    13    myecho '--------------------------------------';
    14      echo '***' $FILE 'exists! ***';
    15 #  ^^ Setting to "myecho" results in the "test -e" displays the file names
    16 else
    17    myecho 'Sorry,' $FILE 'does not exist'
    18    exit
    19 fi

有2个问题:

上面的脚本工作正常。 但是,如果我将第 15 行更改为以“myecho”而不是“echo”开头,则第 12 行的 test -f 命令的结果将包含在子例程看到的 $* arguments 中。

当第 14 行以“myecho”开头时,终端和日志文件的 output 是:

--------------------------------------
afile bfile cfile dfile /tmp/testdir/afile exists! afile bfile cfile dfile

如果第 15 行仅以“echo”开头,则 output 符合预期(但未写入 $logfile):

--------------------------------------
/tmp/testdir/afile exists!
 

Q1)为什么“test -f”的output(我试过其他的forms,在别处也看到过)包含了当前目录下所有文件的名字?

(当前目录中有 4 个文件,分别是“afile”、“bfile”、“cfile”和“dfile”。如果我“cd /tmp”然后运行脚本,/tmp 目录中的所有文件名都是显示。)

Q2) 将第 14 行从“echo”更改为“myecho”如何使它们成为记录的 arguments 的一部分?

$*未加引号。 $*扩展为*****扩展为当前目录中的文件。 就像ls *a='*'; ls $a a='*'; ls $a

引用变量扩展。

使用 shellcheck 检查你的脚本。

在这种情况下,我会使用"$@"而不是"$*"来让 output 通过回声而不是 IFS 由空格连接。

myecho () {
   echo "$@"
   echo "$@" >> "$logfile"
}

另一种选择可能是

myecho() {
  tee -a "$logfile" <<<"$@"
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM