Enable syntax highlight in README.md code block
This commit is contained in:
parent
f73736e5c9
commit
76ad5dbb9f
200
README.md
200
README.md
|
@ -119,8 +119,10 @@ On Solus:
|
||||||
|
|
||||||
From Docker Hub:
|
From Docker Hub:
|
||||||
|
|
||||||
docker pull koalaman/shellcheck:latest # Or :v0.4.6 for a release version
|
```sh
|
||||||
docker run -v "$PWD:/mnt" koalaman/shellcheck myscript
|
docker pull koalaman/shellcheck:latest # Or :v0.4.6 for a release version
|
||||||
|
docker run -v "$PWD:/mnt" koalaman/shellcheck myscript
|
||||||
|
```
|
||||||
|
|
||||||
or use `koalaman/shellcheck-alpine` if you want a larger Alpine Linux based image to extend.
|
or use `koalaman/shellcheck-alpine` if you want a larger Alpine Linux based image to extend.
|
||||||
|
|
||||||
|
@ -180,12 +182,16 @@ This will compile ShellCheck and install it to your `~/.cabal/bin` directory.
|
||||||
|
|
||||||
Add this directory to your `PATH` (for bash, add this to your `~/.bashrc`):
|
Add this directory to your `PATH` (for bash, add this to your `~/.bashrc`):
|
||||||
|
|
||||||
export PATH="$HOME/.cabal/bin:$PATH"
|
```sh
|
||||||
|
export PATH="$HOME/.cabal/bin:$PATH"
|
||||||
|
```
|
||||||
|
|
||||||
Log out and in again, and verify that your PATH is set up correctly:
|
Log out and in again, and verify that your PATH is set up correctly:
|
||||||
|
|
||||||
$ which shellcheck
|
```sh
|
||||||
~/.cabal/bin/shellcheck
|
$ which shellcheck
|
||||||
|
~/.cabal/bin/shellcheck
|
||||||
|
```
|
||||||
|
|
||||||
On native Windows, the `PATH` should already be set up, but the system
|
On native Windows, the `PATH` should already be set up, but the system
|
||||||
may use a legacy codepage. In `cmd.exe`, `powershell.exe` and Powershell ISE,
|
may use a legacy codepage. In `cmd.exe`, `powershell.exe` and Powershell ISE,
|
||||||
|
@ -213,129 +219,147 @@ So what kind of things does ShellCheck look for? Here is an incomplete list of d
|
||||||
|
|
||||||
ShellCheck can recognize several types of incorrect quoting:
|
ShellCheck can recognize several types of incorrect quoting:
|
||||||
|
|
||||||
echo $1 # Unquoted variables
|
```sh
|
||||||
find . -name *.ogg # Unquoted find/grep patterns
|
echo $1 # Unquoted variables
|
||||||
rm "~/my file.txt" # Quoted tilde expansion
|
find . -name *.ogg # Unquoted find/grep patterns
|
||||||
v='--verbose="true"'; cmd $v # Literal quotes in variables
|
rm "~/my file.txt" # Quoted tilde expansion
|
||||||
for f in "*.ogg" # Incorrectly quoted 'for' loops
|
v='--verbose="true"'; cmd $v # Literal quotes in variables
|
||||||
touch $@ # Unquoted $@
|
for f in "*.ogg" # Incorrectly quoted 'for' loops
|
||||||
echo 'Don't forget to restart!' # Singlequote closed by apostrophe
|
touch $@ # Unquoted $@
|
||||||
echo 'Don\'t try this at home' # Attempting to escape ' in ''
|
echo 'Don't forget to restart!' # Singlequote closed by apostrophe
|
||||||
echo 'Path is $PATH' # Variables in single quotes
|
echo 'Don\'t try this at home' # Attempting to escape ' in ''
|
||||||
trap "echo Took ${SECONDS}s" 0 # Prematurely expanded trap
|
echo 'Path is $PATH' # Variables in single quotes
|
||||||
|
trap "echo Took ${SECONDS}s" 0 # Prematurely expanded trap
|
||||||
|
```
|
||||||
|
|
||||||
### Conditionals
|
### Conditionals
|
||||||
|
|
||||||
ShellCheck can recognize many types of incorrect test statements.
|
ShellCheck can recognize many types of incorrect test statements.
|
||||||
|
|
||||||
[[ n != 0 ]] # Constant test expressions
|
```sh
|
||||||
[[ -e *.mpg ]] # Existence checks of globs
|
[[ n != 0 ]] # Constant test expressions
|
||||||
[[ $foo==0 ]] # Always true due to missing spaces
|
[[ -e *.mpg ]] # Existence checks of globs
|
||||||
[[ -n "$foo " ]] # Always true due to literals
|
[[ $foo==0 ]] # Always true due to missing spaces
|
||||||
[[ $foo =~ "fo+" ]] # Quoted regex in =~
|
[[ -n "$foo " ]] # Always true due to literals
|
||||||
[ foo =~ re ] # Unsupported [ ] operators
|
[[ $foo =~ "fo+" ]] # Quoted regex in =~
|
||||||
[ $1 -eq "shellcheck" ] # Numerical comparison of strings
|
[ foo =~ re ] # Unsupported [ ] operators
|
||||||
[ $n && $m ] # && in [ .. ]
|
[ $1 -eq "shellcheck" ] # Numerical comparison of strings
|
||||||
[ grep -q foo file ] # Command without $(..)
|
[ $n && $m ] # && in [ .. ]
|
||||||
[[ "$$file" == *.jpg ]] # Comparisons that can't succeed
|
[ grep -q foo file ] # Command without $(..)
|
||||||
(( 1 -lt 2 )) # Using test operators in ((..))
|
[[ "$$file" == *.jpg ]] # Comparisons that can't succeed
|
||||||
|
(( 1 -lt 2 )) # Using test operators in ((..))
|
||||||
|
```
|
||||||
|
|
||||||
### Frequently misused commands
|
### Frequently misused commands
|
||||||
|
|
||||||
ShellCheck can recognize instances where commands are used incorrectly:
|
ShellCheck can recognize instances where commands are used incorrectly:
|
||||||
|
|
||||||
grep '*foo*' file # Globs in regex contexts
|
```sh
|
||||||
find . -exec foo {} && bar {} \; # Prematurely terminated find -exec
|
grep '*foo*' file # Globs in regex contexts
|
||||||
sudo echo 'Var=42' > /etc/profile # Redirecting sudo
|
find . -exec foo {} && bar {} \; # Prematurely terminated find -exec
|
||||||
time --format=%s sleep 10 # Passing time(1) flags to time builtin
|
sudo echo 'Var=42' > /etc/profile # Redirecting sudo
|
||||||
while read h; do ssh "$h" uptime # Commands eating while loop input
|
time --format=%s sleep 10 # Passing time(1) flags to time builtin
|
||||||
alias archive='mv $1 /backup' # Defining aliases with arguments
|
while read h; do ssh "$h" uptime # Commands eating while loop input
|
||||||
tr -cd '[a-zA-Z0-9]' # [] around ranges in tr
|
alias archive='mv $1 /backup' # Defining aliases with arguments
|
||||||
exec foo; echo "Done!" # Misused 'exec'
|
tr -cd '[a-zA-Z0-9]' # [] around ranges in tr
|
||||||
find -name \*.bak -o -name \*~ -delete # Implicit precedence in find
|
exec foo; echo "Done!" # Misused 'exec'
|
||||||
f() { whoami; }; sudo f # External use of internal functions
|
find -name \*.bak -o -name \*~ -delete # Implicit precedence in find
|
||||||
|
f() { whoami; }; sudo f # External use of internal functions
|
||||||
|
```
|
||||||
|
|
||||||
### Common beginner's mistakes
|
### Common beginner's mistakes
|
||||||
|
|
||||||
ShellCheck recognizes many common beginner's syntax errors:
|
ShellCheck recognizes many common beginner's syntax errors:
|
||||||
|
|
||||||
var = 42 # Spaces around = in assignments
|
```sh
|
||||||
$foo=42 # $ in assignments
|
var = 42 # Spaces around = in assignments
|
||||||
for $var in *; do ... # $ in for loop variables
|
$foo=42 # $ in assignments
|
||||||
var$n="Hello" # Wrong indirect assignment
|
for $var in *; do ... # $ in for loop variables
|
||||||
echo ${var$n} # Wrong indirect reference
|
var$n="Hello" # Wrong indirect assignment
|
||||||
var=(1, 2, 3) # Comma separated arrays
|
echo ${var$n} # Wrong indirect reference
|
||||||
array=( [index] = value ) # Incorrect index initialization
|
var=(1, 2, 3) # Comma separated arrays
|
||||||
echo "Argument 10 is $10" # Positional parameter misreference
|
array=( [index] = value ) # Incorrect index initialization
|
||||||
if $(myfunction); then ..; fi # Wrapping commands in $()
|
echo "Argument 10 is $10" # Positional parameter misreference
|
||||||
else if othercondition; then .. # Using 'else if'
|
if $(myfunction); then ..; fi # Wrapping commands in $()
|
||||||
|
else if othercondition; then .. # Using 'else if'
|
||||||
|
```
|
||||||
|
|
||||||
### Style
|
### Style
|
||||||
|
|
||||||
ShellCheck can make suggestions to improve style:
|
ShellCheck can make suggestions to improve style:
|
||||||
|
|
||||||
[[ -z $(find /tmp | grep mpg) ]] # Use grep -q instead
|
```sh
|
||||||
a >> log; b >> log; c >> log # Use a redirection block instead
|
[[ -z $(find /tmp | grep mpg) ]] # Use grep -q instead
|
||||||
echo "The time is `date`" # Use $() instead
|
a >> log; b >> log; c >> log # Use a redirection block instead
|
||||||
cd dir; process *; cd ..; # Use subshells instead
|
echo "The time is `date`" # Use $() instead
|
||||||
echo $[1+2] # Use standard $((..)) instead of old $[]
|
cd dir; process *; cd ..; # Use subshells instead
|
||||||
echo $(($RANDOM % 6)) # Don't use $ on variables in $((..))
|
echo $[1+2] # Use standard $((..)) instead of old $[]
|
||||||
echo "$(date)" # Useless use of echo
|
echo $(($RANDOM % 6)) # Don't use $ on variables in $((..))
|
||||||
cat file | grep foo # Useless use of cat
|
echo "$(date)" # Useless use of echo
|
||||||
|
cat file | grep foo # Useless use of cat
|
||||||
|
```
|
||||||
|
|
||||||
### Data and typing errors
|
### Data and typing errors
|
||||||
|
|
||||||
ShellCheck can recognize issues related to data and typing:
|
ShellCheck can recognize issues related to data and typing:
|
||||||
|
|
||||||
args="$@" # Assigning arrays to strings
|
```sh
|
||||||
files=(foo bar); echo "$files" # Referencing arrays as strings
|
args="$@" # Assigning arrays to strings
|
||||||
declare -A arr=(foo bar) # Associative arrays without index
|
files=(foo bar); echo "$files" # Referencing arrays as strings
|
||||||
printf "%s\n" "Arguments: $@." # Concatenating strings and arrays
|
declare -A arr=(foo bar) # Associative arrays without index
|
||||||
[[ $# > 2 ]] # Comparing numbers as strings
|
printf "%s\n" "Arguments: $@." # Concatenating strings and arrays
|
||||||
var=World; echo "Hello " var # Unused lowercase variables
|
[[ $# > 2 ]] # Comparing numbers as strings
|
||||||
echo "Hello $name" # Unassigned lowercase variables
|
var=World; echo "Hello " var # Unused lowercase variables
|
||||||
cmd | read bar; echo $bar # Assignments in subshells
|
echo "Hello $name" # Unassigned lowercase variables
|
||||||
|
cmd | read bar; echo $bar # Assignments in subshells
|
||||||
|
```
|
||||||
|
|
||||||
### Robustness
|
### Robustness
|
||||||
|
|
||||||
ShellCheck can make suggestions for improving the robustness of a script:
|
ShellCheck can make suggestions for improving the robustness of a script:
|
||||||
|
|
||||||
rm -rf "$STEAMROOT/"* # Catastrophic rm
|
```sh
|
||||||
touch ./-l; ls * # Globs that could become options
|
rm -rf "$STEAMROOT/"* # Catastrophic rm
|
||||||
find . -exec sh -c 'a && b {}' \; # Find -exec shell injection
|
touch ./-l; ls * # Globs that could become options
|
||||||
printf "Hello $name" # Variables in printf format
|
find . -exec sh -c 'a && b {}' \; # Find -exec shell injection
|
||||||
for f in $(ls *.txt); do # Iterating over ls output
|
printf "Hello $name" # Variables in printf format
|
||||||
export MYVAR=$(cmd) # Masked exit codes
|
for f in $(ls *.txt); do # Iterating over ls output
|
||||||
|
export MYVAR=$(cmd) # Masked exit codes
|
||||||
|
```
|
||||||
|
|
||||||
### Portability
|
### Portability
|
||||||
|
|
||||||
ShellCheck will warn when using features not supported by the shebang. For example, if you set the shebang to `#!/bin/sh`, ShellCheck will warn about portability issues similar to `checkbashisms`:
|
ShellCheck will warn when using features not supported by the shebang. For example, if you set the shebang to `#!/bin/sh`, ShellCheck will warn about portability issues similar to `checkbashisms`:
|
||||||
|
|
||||||
echo {1..$n} # Works in ksh, but not bash/dash/sh
|
```sh
|
||||||
echo {1..10} # Works in ksh and bash, but not dash/sh
|
echo {1..$n} # Works in ksh, but not bash/dash/sh
|
||||||
echo -n 42 # Works in ksh, bash and dash, undefined in sh
|
echo {1..10} # Works in ksh and bash, but not dash/sh
|
||||||
trap 'exit 42' sigint # Unportable signal spec
|
echo -n 42 # Works in ksh, bash and dash, undefined in sh
|
||||||
cmd &> file # Unportable redirection operator
|
trap 'exit 42' sigint # Unportable signal spec
|
||||||
read foo < /dev/tcp/host/22 # Unportable intercepted files
|
cmd &> file # Unportable redirection operator
|
||||||
foo-bar() { ..; } # Undefined/unsupported function name
|
read foo < /dev/tcp/host/22 # Unportable intercepted files
|
||||||
[ $UID = 0 ] # Variable undefined in dash/sh
|
foo-bar() { ..; } # Undefined/unsupported function name
|
||||||
local var=value # local is undefined in sh
|
[ $UID = 0 ] # Variable undefined in dash/sh
|
||||||
time sleep 1 | sleep 5 # Undefined uses of 'time'
|
local var=value # local is undefined in sh
|
||||||
|
time sleep 1 | sleep 5 # Undefined uses of 'time'
|
||||||
|
```
|
||||||
|
|
||||||
### Miscellaneous
|
### Miscellaneous
|
||||||
|
|
||||||
ShellCheck recognizes a menagerie of other issues:
|
ShellCheck recognizes a menagerie of other issues:
|
||||||
|
|
||||||
PS1='\e[0;32m\$\e[0m ' # PS1 colors not in \[..\]
|
```sh
|
||||||
PATH="$PATH:~/bin" # Literal tilde in $PATH
|
PS1='\e[0;32m\$\e[0m ' # PS1 colors not in \[..\]
|
||||||
rm “file” # Unicode quotes
|
PATH="$PATH:~/bin" # Literal tilde in $PATH
|
||||||
echo "Hello world" # Carriage return / DOS line endings
|
rm “file” # Unicode quotes
|
||||||
echo hello \ # Trailing spaces after \
|
echo "Hello world" # Carriage return / DOS line endings
|
||||||
var=42 echo $var # Expansion of inlined environment
|
echo hello \ # Trailing spaces after \
|
||||||
#!/bin/bash -x -e # Common shebang errors
|
var=42 echo $var # Expansion of inlined environment
|
||||||
echo $((n/180*100)) # Unnecessary loss of precision
|
#!/bin/bash -x -e # Common shebang errors
|
||||||
ls *[:digit:].txt # Bad character class globs
|
echo $((n/180*100)) # Unnecessary loss of precision
|
||||||
sed 's/foo/bar/' file > file # Redirecting to input
|
ls *[:digit:].txt # Bad character class globs
|
||||||
|
sed 's/foo/bar/' file > file # Redirecting to input
|
||||||
|
```
|
||||||
|
|
||||||
## Testimonials
|
## Testimonials
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue