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. 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:
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:
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.
The output to both the terminal and the log file when line 14 starts with "myecho" is:
--------------------------------------
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):
--------------------------------------
/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?
(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.)
Q2) How does changing line 14 from " echo " to "myecho" cause them to be part of the arguments logged?
CodePudding user response:
$*
is unquoted. $*
expands to *****
which expands to files in current directory. Just like ls *
, or a='*'; ls $a
.
Quote variable expansions.
Check your scripts with shellcheck.
In this case, I would use "$@"
instead of "$*"
to have the output joined by spaces by echo, not by IFS.
myecho () {
echo "$@"
echo "$@" >> "$logfile"
}
CodePudding user response:
Another alternative might be
myecho() {
tee -a "$logfile" <<<"$@"
}