Pattern: Use of glob in [ ]
Issue: -
Globs in [ ]
will expand to a sequence of words, one per matching filename. Meanwhile, operators work on single words.
Example of incorrect code:
[ current.log -nt backup/*.log ] && echo "This is the latest file"
This is equivalent to [ current.log -nt backup/file1.log backup/file2.log backup/file3.log ]
, which is invalid syntax. A typical error message is bash: [: too many arguments
or dash: somefile: unexpected operator
.
Instead, use a for
loop to iterate over matching filenames, and apply your condition to each.
Example of correct code:
newerThanAll=true
for log in backup/*.log
do
[ current.log -nt "$log" ] || newerThanAll=false
done
[ "$newerThanAll" = "true" ] && echo "This is the latest file"
If you know your glob will only ever match one file, you can check this explicitly and use the first file:
set -- backup/*.log
[ $# -eq 1 ] || { echo "There are too many matches."; exit 1; }
[ file.log -nt "$1" ] && echo "This is the latest file"
Alternatively, ignore this warning.