From bca300e529ac0152976604bdc89acbf8b8d44173 Mon Sep 17 00:00:00 2001 From: Vidar Holen Date: Sat, 27 Apr 2019 16:10:36 -0700 Subject: [PATCH] Updated SC2089 (markdown) --- SC2089.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/SC2089.md b/SC2089.md index fd9ebe1..5edac7b 100644 --- a/SC2089.md +++ b/SC2089.md @@ -9,6 +9,8 @@ ls $args ### Correct code: +In Bash/Ksh with arrays: + ```sh args=(-lh "My File.txt") ls "${args[@]}" @@ -21,6 +23,13 @@ set -- -lh "My File.txt" ls "$@" ``` +or in POSIX via functions: + +```sh +myls() { ls "-lh" "My File.txt"; } +myls +``` + ### Rationale: Bash does not interpret data as code. Consider almost any other languages, such as Python: @@ -37,7 +46,16 @@ Similarly, `"My File.txt"` is Bash syntax for a single word with a space in it. The solution is to use an array instead, whenever possible. -If due to `sh` compatibility you can't use arrays, you can use `eval` instead. However, this is very insecure and easy to get wrong, leading to various forms of security vulnerabilities and breakage: +If due to `sh` compatibility you can't use arrays, you can sometimes use functions instead. Instead of trying to create a set of arguments that has to be passed to a command, create a function that calls the function with arguments plus some more: + +```sh +ffmpeg_with_args() { + ffmpeg -filter_complex '[#0x2ef] setpts=PTS+1/TB [sub] ; [#0x2d0] [sub] overlay' "$@" +} +ffmpeg_with_args -i "My File.avi" "Output.avi" +``` + +In other cases, you may have to use `eval` instead, though this is often fragile and insecure. If you get it wrong, it'll appear to work great in all test cases, and may still lead to various forms of security vulnerabilities and breakage: ```sh quote() { local q=${1//\'/\'\\\'\'}; echo "'$q'"; }