diff --git a/SC2039.md b/SC2039.md index a7d1c35..94038a9 100644 --- a/SC2039.md +++ b/SC2039.md @@ -1,4 +1,4 @@ -## #!/bin/sh was specified, but _____ is not standard. +## `#!/bin/sh` was specified, but _____ is not standard. The shebang indicates that the script works with `/bin/sh`, but you are using non-standard features that may not be supported. @@ -6,4 +6,104 @@ It may currently work for you, but it can or will fail on other OS, the same OS Either declare a specific shell like `#!/usr/bin/env bash` to make sure this shell is always used, or rewrite the script in a portable way. -For help with rewrites, the Ubuntu wiki has [a list of portability issues](https://wiki.ubuntu.com/DashAsBinSh) that broke people's `#!/bin/sh` scripts when Ubuntu switched from Bash to Dash. ShellCheck may not warn about all these issues. \ No newline at end of file +For help with rewrites, the Ubuntu wiki has [a list of portability issues](https://wiki.ubuntu.com/DashAsBinSh) that broke people's `#!/bin/sh` scripts when Ubuntu switched from Bash to Dash. ShellCheck may not warn about all these issues. + +### `$'c-style-escapes'` + +Bashism: + +```Bash +a=$' \t\n' +``` + +POSIX: + +```sh +a="$(printf '%b_' ' \t\n')"; a="${a%_}" # protect trailing \n +``` + +### `$"msgid"` + +Bashism: + +```Bash +echo $"foo $(bar) baz" +``` + +POSIX: + +```sh +. gettext.sh # GNU Gettext sh library +# ... +barout=$(bar) +eval_gettext 'foo $barout baz' # GNU Gettext automatically echos. See their doc for more info. +``` + +Or you can change them to normal double quotes so you go without `gettext`. + +### Arithmetic `for` loops + +Bash: + +```Bash +for ((init; test; next)); do foo; done +``` + +POSIX: + +```sh +: $((init)) +while [ $((test)) -ne 0 ]; do foo; : $((next)); done +``` + +### standalone `((..))` + +Bash: + +```Bash +((a=c+d)) +((d)) && echo d is true. +``` + +POSIX: + +```sh +: $((a=c+d)) +[ $((d)) -ne 0 ] && echo d is true. +``` + +### `select` loops + +It takes extra care over terminal columns to make select loop look like bash's, which generates a list with multiple items on one line, or like `ls`. + +It is, however, still possible to make a naive translation for `select foo in bar baz; do eat; done`: + +```sh +while + _i=0 _foo= foo= + for _name in bar baz; do echo "$((_i+=1))) $_name"; done + printf '$# '; read _foo +do + [ "$foo" -le "$_i" ]] || continue + case _foo in 1) foo=bar;; 2) foo=baz;; esac + eat +done +``` + +### Here-strings + +Bash: + +```Bash +grep aaa <<< "$g" +``` + +POSIX: + +```sh +printf '%s' "$g" | grep aaa # since we want to avoid `echo` +``` + +### echo flags + +See koalaman/shellcheck#461. \ No newline at end of file