Home > Blockchain >  Why are results of "test -f" displayed on the terminal and included in parameters passed t
Why are results of "test -f" displayed on the terminal and included in parameters passed t

Time:01-31

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" <<<"$@"
}
  • Related