diff --git a/SC2202.md b/SC2202.md new file mode 100644 index 0000000..dc63e6f --- /dev/null +++ b/SC2202.md @@ -0,0 +1,39 @@ +## Globs don't work as operands in [ ]. Use a loop. + +### Problematic code: + +```sh +[ current.log -nt backup/*.log ] && echo "This is the latest file" + +``` + +### Correct code: + +```sh +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. + +Instead, you can iterate over the filenames you want with a loop, and apply your condition to each filename. + +### 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. \ No newline at end of file