简体   繁体   English

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

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

I'm trying to write a bash subroutine that will work like the "echo" command, except to display the text both on the terminal and to write them to a log file.我正在尝试编写一个 bash 子例程,它将像“echo”命令一样工作,除了在终端上显示文本并将它们写入日志文件。 Seems simple enough, but it isn't working like I think it should--it's including the names of the files in the current directory.看起来很简单,但它并没有像我认为的那样工作——它包括当前目录中的文件名。

Here's a sample script with the "myecho" routine:这是带有“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

There are 2 issues:有2个问题:

The script above works fine.上面的脚本工作正常。 But if I change line 15 to start with "myecho" instead of "echo", the results of the test -f command on line 12 are included in the $* arguments the subroutine sees.但是,如果我将第 15 行更改为以“myecho”而不是“echo”开头,则第 12 行的 test -f 命令的结果将包含在子例程看到的 $* arguments 中。

The output to both the terminal and the log file when line 14 starts with "myecho" is:当第 14 行以“myecho”开头时,终端和日志文件的 output 是:

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

If line 15 starts with just "echo", the output is as expected (but not written to the $logfile):如果第 15 行仅以“echo”开头,则 output 符合预期(但未写入 $logfile):

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

Q1) Why does output of the "test -f" (and I've tried other forms, and seen it elsewhere), include the names of all the files in the current directory? Q1)为什么“test -f”的output(我试过其他的forms,在别处也看到过)包含了当前目录下所有文件的名字?

(There are 4 files in this current directory are "afile", "bfile", "cfile" and "dfile". If I "cd /tmp" and then run the script, all of the file names in the /tmp directory are displayed.) (当前目录中有 4 个文件,分别是“afile”、“bfile”、“cfile”和“dfile”。如果我“cd /tmp”然后运行脚本,/tmp 目录中的所有文件名都是显示。)

Q2) How does changing line 14 from " echo " to "myecho" cause them to be part of the arguments logged? Q2) 将第 14 行从“echo”更改为“myecho”如何使它们成为记录的 arguments 的一部分?

$* is unquoted. $*未加引号。 $* expands to ***** which expands to files in current directory. $*扩展为*****扩展为当前目录中的文件。 Just like ls * , or a='*'; ls $a就像ls *a='*'; ls $a a='*'; ls $a . a='*'; ls $a

Quote variable expansions.引用变量扩展。

Check your scripts with shellcheck.使用 shellcheck 检查你的脚本。

In this case, I would use "$@" instead of "$*" to have the output joined by spaces by echo, not by IFS.在这种情况下,我会使用"$@"而不是"$*"来让 output 通过回声而不是 IFS 由空格连接。

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

Another alternative might be另一种选择可能是

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

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

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