[英]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.