Added alternatives.

Mingye Wang
2015-09-18 23:25:53 -04:00
parent 19a6c3b72d
commit c1481c396c

102
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.
@@ -7,3 +7,103 @@ 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.
### `$'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.