Skip to content
Joachim Ansorg edited this page Nov 12, 2021 · 3 revisions

Globs don't work as operands in [ ]. Use a loop.

Problematic code:

[ current.log -nt backup/*.log ] && echo "This is the latest file"

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"

Rationale:

Globs in [ ] will expand to a sequence of words, one per matching filename. Meanwhile, operators work on single words.

The problematic code 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.

Exceptions:

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.

ShellCheck

Each individual ShellCheck warning has its own wiki page like SC1000. Use GitHub Wiki's "Pages" feature above to find a specific one, or see Checks.

Clone this wiki locally