From 2660d91200c49ddd3ace7e215f9a7304de8aa3db Mon Sep 17 00:00:00 2001 From: Vidar Holen Date: Tue, 3 Aug 2021 13:19:07 -0700 Subject: [PATCH] Created SC2295 (markdown) --- SC2295.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 SC2295.md diff --git a/SC2295.md b/SC2295.md new file mode 100644 index 0000000..7ac0ec3 --- /dev/null +++ b/SC2295.md @@ -0,0 +1,43 @@ +## Expansions inside ${..} need to be quoted separately, otherwise they will match as a pattern. + +### Problematic code: + +```sh +relative_path() { + printf '%s\n' "${2#$1}" +} + +# Results in "/tmp/King_Kong_[1933]/extras/trailer.mkv" because the prefix fails to match +relative_path "/tmp/King_Kong_[1933]/" "/tmp/King_Kong_[1933]/extras/trailer.mkv" + +# Results in "cover.jpg" even though the prefix is different +relative_path "/tmp/King_Kong_[1933]/" "/tmp/King_Kong_3/cover.jpg" + +``` + +### Correct code: + +```sh +relative_path() { + printf '%s\n' "${2#"$1"}" +} +# Results in "extras/trailer.mkv" as expected +relative_path "/tmp/King_Kong_[1933]/" "/tmp/King_Kong_[1933]/extras/trailer.mkv" + +# Results in "/tmp/King_Kong_3/cover.jpg" as expected +relative_path "/tmp/King_Kong_[1933]/" "/tmp/King_Kong_3/cover.jpg" +``` + +### Rationale: + +When using expansions in a parameter expansion prefix/suffix expression, the expansion needs to be quoted separately or it will match as a pattern. The quotes around the outer parameter expansion does not protect against this. + +This means that any variable that contains e.g. brackets, asterisks or question marks may not match as expected. In the example, `[1933]` was interpreted as a pattern character range and would therefore match `/tmp/King_Kong_3/` but not `/tmp/King_Kong_[1933]/` as was the intention. + +### Exceptions: + +If you wanted to treat the string as a pattern, such as `suffix=".*"; file="${var%$suffix}";` then you can [[ignore]] this suggestion. + +### Related resources: + +* Help by adding links to BashFAQ, StackOverflow, man pages, POSIX, etc! \ No newline at end of file