0

I am writing a bash script for backup with log storage.

  • I use my defined function as follows:

    logit () {
        echo " $1  $2 "  >> /path/to/log
    }
    
  • For logit 'Starting Backup' $(date +'%D %T') I get this output:

    Starting Backup 01/11/22
    

    so the time is missing, apparently the stdout function has shortened it.

  • With echo $(date +'%D %T') I also get the time in the stdout.

  • I would also like to use my function for logs, e.g.

    logit 'DB-LOGS' $(cat /path/to/sql)
    

    results in

    DB-LOG mysqldump:
    

    Again, some stdout is missing here.

What should I change or add to the function to get complete output?

AdminBee
  • 22,803

2 Answers2

4

Double quote the command substitution:

logit 'Starting Backup' "$(date +'%D %T')"

Without quotes, the result of $(date ...) goes through word splitting and filename globbing. There's no shortening: assuming $IFS is still set to its default value (which does contain the space character), the date and time are passed as separate arguments to the function, the time ends up in $3 which you don't use.

choroba
  • 47,233
4

You could use "$*" in your script to concatenate all parameters to one string.

logit () {
    echo " $* "  >> /path/to/log
}

("$*" uses the first character of IFS as joiner, a space by default.)

Or, if you want the extra spaces around each arg, use printf with "$@":

logit () {
    { printf " %s " "$@"; echo; } >> /path/to/log
}

(Here, "$@" expands to each arg separately, and printf repeats the format string as many times as needed. echo adds the final newline.)

ilkkachu
  • 138,973
  • If you want to create a single string from the positional parameters, use $* inside the quoted string. If you want to create multiple arguments for echo, use "$@" with no spaces around $@. – Kusalananda Jan 11 '22 at 13:21
  • @they The " $@ " is also a single argument. I thought it closer to the OP's intention. – Gerard H. Pille Jan 11 '22 at 13:30
  • 1
    " $@ " is two arguments if there are two positional parameters (the same as " $1" "$2 "). You would recreate " $1 $2 " with " $* ", assuming the first character of $IFS is a space. – Kusalananda Jan 11 '22 at 14:05
  • Strange, ksh tells me differently, concerning the " $@ ". – Gerard H. Pille Jan 11 '22 at 14:09
  • Which ksh is that? Both pdksh and ksh93 produces two lines from set -- "a b" "c d"; printf '"%s"\n' " $@ ". This user tagged their question with [tag:bash], and that shell behaves the same, as does dash. – Kusalananda Jan 11 '22 at 14:13
  • @GerardH.Pille, "$@" results in multiple arguments, "$*" produces one. Here, with two args, it's the difference between echo "$1" "$2" and echo "$1 $2". ...which in the case of echo is hard to tell, since echo itself does the same as "$*" (with default IFS), it joins the args with spaces in between. But "$*" is arguably more "correct" here, and as said, you'd see the difference with e.g. printf "%s\n" "$@". – ilkkachu Jan 12 '22 at 14:01