Shell Script Wildcards – Issues with Output Redirection

bashscriptingshellshell-scriptwildcards

Say I have two scripts:

  • script1.sh:

    #!/bin/bash
    version=2.6
    log_file="$HOME/log-file-version-$version.log"
    
    touch $log_file &>/dev/null
    
    echo "log to my log file from script 1" >> $HOME/log-file-version-?.?.log
    
    gnome-terminal --tab --active --title="script2" --  sh script2.sh
    
  • script2.sh:

    #!/bin/bash
    
    echo "log to my log file from script 2" >> $HOME/log-file-version-?.?.log
    

I run script1.sh.

I'm left with two log files in my home:

log-file-version-2.6.log
log-file-version-?.?.log

log-file-version-2.6.log contains:

log to my log file from script 1

log-file-version-?.?.log contains:

log to my log file from script 2

which means that in script 1 the wildcards from line 7 (>> $HOME/log-file-version-?.?.log) were correctly interpreted, but when a script is run with sh these wildcards don't work.

Why is that and how can I fix this?

I need to use wildcards because I don't want to be passing arguments from shell script to shell script and I want them to be self-sufficient.

I'm using Ubuntu and running these scripts from the default terminal which is gnome-terminal.

Best Answer

The bash manual has this to say in the 3.6 Redirections section:

The word following the redirection operator in the following descriptions, unless otherwise noted, is subjected to brace expansion, tilde expansion, parameter expansion, command substitution, arithmetic expansion, quote removal, filename expansion, and word splitting. If it expands to more than one word, Bash reports an error.

sh does not do that: from the POSIX shell specification

If the redirection operator is "<<" or "<<-", [...]. For the other redirection operators, the word that follows the redirection operator shall be subjected to tilde expansion, parameter expansion, command substitution, arithmetic expansion, and quote removal. Pathname expansion shall not be performed on the word by a non-interactive shell; an interactive shell may perform it, but shall do so only when the expansion would result in one word.

$ dash
$ echo foo > *
$ ls
'*'  README.md  ...
$ bash
$ echo bar >> *
bash: *: ambiguous redirect
Related Question