From 5d471fa43bfe8f2ee3bc53e6b4d81cac3404bb76 Mon Sep 17 00:00:00 2001 From: koalaman Date: Sat, 31 Dec 2016 13:32:19 -0800 Subject: [PATCH] Created SC2202 (markdown) --- SC2202.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 SC2202.md 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