mirror of
https://github.com/koalaman/shellcheck.git
synced 2025-10-03 11:19:45 +08:00
Added alternatives.
104
SC2039.md
104
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.
|
||||
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.
|
Reference in New Issue
Block a user