ShellCheck adalah alat GPLv3 yang memberikan peringatan dan saran untuk skrip shell bash/sh:
Tujuan dari ShellCheck adalah
Untuk menunjukkan dan memperjelas masalah sintaksis pemula yang umum yang menyebabkan shell memberikan pesan kesalahan samar.
Untuk menunjukkan dan memperjelas masalah semantik tingkat menengah yang menyebabkan shell berperilaku aneh dan berlawanan dengan intuisi.
Untuk menunjukkan peringatan halus, kasus sudut, dan jebakan yang dapat menyebabkan skrip yang berfungsi pada pengguna tingkat lanjut gagal dalam keadaan di masa mendatang.
Lihat galeri kode buruk untuk mengetahui contoh apa yang ShellCheck dapat bantu Anda identifikasi!
Ada beberapa cara untuk menggunakan ShellCheck!
Tempelkan skrip shell di https://www.shellcheck.net untuk mendapatkan masukan instan.
ShellCheck.net selalu disinkronkan ke git commit terbaru, dan merupakan cara termudah untuk mencoba ShellCheck. Beritahu temanmu!
Jalankan shellcheck yourscript
di terminal Anda untuk keluaran instan, seperti yang terlihat di atas.
Anda dapat melihat saran ShellCheck langsung di berbagai editor.
.
.
Sublim, melalui SublimeLinter.
Pulsar Edit (sebelumnya Atom), melalui linter-shellcheck-pulsar.
VSCode, melalui vscode-shellcheck.
Kebanyakan editor lain, melalui kompatibilitas kesalahan GCC.
Meskipun ShellCheck sebagian besar ditujukan untuk penggunaan interaktif, ShellCheck dapat dengan mudah ditambahkan ke build atau rangkaian pengujian. Itu menggunakan kode keluar secara kanonik, jadi Anda cukup menambahkan perintah shellcheck
sebagai bagian dari proses.
Misalnya, di Makefile:
check-scripts :
# Fail if any of these files have warnings
shellcheck myscripts/*.sh
atau dalam file .travis.yml
Travis CI:
script :
# Fail if any of these files have warnings
- shellcheck myscripts/*.sh
Layanan dan platform yang sudah menginstal ShellCheck dan siap digunakan:
Sebagian besar layanan lain, termasuk GitLab, memungkinkan Anda menginstal ShellCheck sendiri, baik melalui manajer paket sistem (lihat Menginstal), atau dengan mengunduh dan membongkar rilis biner.
Sebaiknya instal versi ShellCheck tertentu secara manual. Hal ini untuk menghindari kerusakan build yang tidak terduga ketika versi baru dengan peringatan baru dipublikasikan.
Untuk pemfilteran atau pelaporan yang disesuaikan, ShellCheck dapat menghasilkan JSON sederhana, XML yang kompatibel dengan CheckStyle, peringatan yang kompatibel dengan GCC, serta teks yang dapat dibaca manusia (dengan atau tanpa warna ANSI). Lihat halaman wiki Integrasi untuk dokumentasi lebih lanjut.
Cara termudah untuk menginstal ShellCheck secara lokal adalah melalui manajer paket Anda.
Pada sistem dengan Cabal (diinstal ke ~/.cabal/bin
):
cabal update
cabal install ShellCheck
Pada sistem dengan Stack (instal ke ~/.local/bin
):
stack update
stack install ShellCheck
Pada distro berbasis Debian:
sudo apt install shellcheck
Pada distro berbasis Arch Linux:
pacman -S shellcheck
atau dapatkan shellcheck-bin bebas ketergantungan dari AUR.
Di distro berbasis Gentoo:
emerge --ask shellcheck
Pada distro berbasis EPEL:
sudo yum -y install epel-release
sudo yum install ShellCheck
Di distro berbasis Fedora:
dnf install ShellCheck
Di FreeBSD:
pkg install hs-ShellCheck
Di macOS (OS X) dengan Homebrew:
brew install shellcheck
Atau dengan MacPorts:
sudo port install shellcheck
Di OpenBSD:
pkg_add shellcheck
Di openSUSE
zypper in ShellCheck
Atau gunakan OneClickInstall - https://software.opensuse.org/package/ShellCheck
Di Solus:
eopkg install shellcheck
Di Windows (melalui coklat):
C: > choco install shellcheck
Atau Windows (melalui winget):
C: > winget install --id koalaman.shellcheck
Atau Windows (melalui sendok):
C: > scoop install shellcheck
Dari conda-forge:
conda install -c conda-forge shellcheck
Dari Toko Snap:
snap install --channel=edge shellcheck
Dari Hub Docker:
docker run --rm -v " $PWD :/mnt " koalaman/shellcheck:stable myscript
# Or :v0.4.7 for that version, or :latest for daily builds
atau gunakan koalaman/shellcheck-alpine
jika Anda ingin memperluas image berbasis Alpine Linux yang lebih besar. Ini bekerja persis seperti gambar Alpine biasa, tetapi shellcheck sudah diinstal sebelumnya.
Menggunakan manajer paket nix:
nix-env -iA nixpkgs.shellcheck
Menggunakan manajer paket Flox
flox install shellcheck
Alternatifnya, Anda dapat mengunduh binari yang telah dikompilasi sebelumnya untuk rilis terbaru di sini:
atau lihat Rilis GitHub untuk rilis lainnya (termasuk rilis meta terbaru untuk build git harian).
Saat ini tidak ada biner resmi untuk Apple Silicon, tetapi versi pihak ketiga tersedia melalui ShellCheck untuk Visual Studio Code.
Paket distro sudah dilengkapi dengan halaman man
. Jika Anda membangun dari sumber, itu dapat diinstal dengan:
pandoc -s -f markdown-smart -t man shellcheck.1.md -o shellcheck.1
sudo mv shellcheck.1 /usr/share/man/man1
Untuk menjalankan ShellCheck melalui pre-commit, tambahkan hook ke .pre-commit-config.yaml
Anda :
repos:
- repo: https://github.com/koalaman/shellcheck-precommit
rev: v0.7.2
hooks:
- id: shellcheck
# args: ["--severity=warning"] # Optionally only show errors and warnings
Travis CI kini telah mengintegrasikan ShellCheck secara default, jadi Anda tidak perlu menginstalnya secara manual.
Jika Anda masih ingin melakukannya untuk meningkatkan versi sesuka Anda atau memastikan Anda menggunakan rilis terbaru, ikuti langkah-langkah di bawah ini untuk menginstal versi biner.
Biner yang telah dikompilasi sebelumnya hadir dalam file tar.xz
Untuk mendekompresinya, pastikan xz
diinstal. Di Debian/Ubuntu/Mint, Anda dapat apt install xz-utils
. Di Redhat/Fedora/CentOS, yum -y install xz
.
Penginstal sederhana dapat melakukan sesuatu seperti:
scversion= " stable " # or "v0.4.7", or "latest"
wget -qO- " https://github.com/koalaman/shellcheck/releases/download/ ${scversion?} /shellcheck- ${scversion?} .linux.x86_64.tar.xz " | tar -xJv
cp " shellcheck- ${scversion} /shellcheck " /usr/bin/
shellcheck --version
Bagian ini menjelaskan cara membangun ShellCheck dari direktori sumber. ShellCheck ditulis dalam Haskell dan membutuhkan 2GB RAM untuk dikompilasi.
ShellCheck dibuat dan dikemas menggunakan Cabal. Instal paket cabal-install
dari manajer paket sistem Anda (misalnya apt-get
, brew
, emerge
, yum
, atau zypper
).
Di macOS (OS X), Anda dapat melakukan instalasi cepat Cabal menggunakan brew, yang memerlukan waktu beberapa menit, bukan lebih dari 30 menit jika Anda mencoba mengkompilasinya dari sumber.
$ brew install cabal-install
Di MacPorts, paket ini disebut hs-cabal-install
, sedangkan pengguna asli Windows harus menginstal versi terbaru platform Haskell dari https://www.haskell.org/platform/
Verifikasi bahwa cabal
telah diinstal dan perbarui daftar ketergantungannya dengan
$ cabal update
git clone
repositori ini, dan cd
ke direktori sumber ShellCheck untuk membangun/menginstal:
$ cabal install
Ini akan mengkompilasi ShellCheck dan menginstalnya ke direktori ~/.cabal/bin
Anda.
Tambahkan direktori ini ke PATH
Anda (untuk bash, tambahkan ini ke ~/.bashrc
):
export PATH= " $HOME /.cabal/bin: $PATH "
Keluar dan masuk lagi, dan verifikasi bahwa PATH Anda sudah diatur dengan benar:
$ which shellcheck
~ /.cabal/bin/shellcheck
Pada Windows asli, PATH
seharusnya sudah diatur, namun sistem mungkin menggunakan halaman kode lama. Di cmd.exe
, powershell.exe
dan Powershell ISE, pastikan untuk menggunakan font TrueType, bukan font Raster, dan atur halaman kode aktif ke UTF-8 (65001) dengan chcp
:
chcp 65001
Di Powershell ISE, Anda mungkin perlu memperbarui pengkodean keluaran tambahan:
[ Console ]::OutputEncoding = [ System.Text.Encoding ]::UTF8
Untuk menjalankan rangkaian pengujian unit:
$ cabal test
Jadi apa saja yang dicari oleh ShellCheck? Berikut adalah daftar lengkap masalah yang terdeteksi.
ShellCheck dapat mengenali beberapa jenis kutipan yang salah:
echo $1 # Unquoted variables
find . -name * .ogg # Unquoted find/grep patterns
rm " ~/my file.txt " # Quoted tilde expansion
v= ' --verbose="true" ' ; cmd $v # Literal quotes in variables
for f in " *.ogg " # Incorrectly quoted 'for' loops
touch $@ # Unquoted $@
echo ' Don ' t forget to restart ! ' # Singlequote closed by apostrophe
echo ' Don ' t try this at home ' # Attempting to escape ' in ' '
echo ' Path is $PATH ' # Variables in single quotes
trap " echo Took ${SECONDS} s " 0 # Prematurely expanded trap
unset var[i] # Array index treated as glob
ShellCheck dapat mengenali banyak jenis pernyataan pengujian yang salah.
[[ n != 0 ]] # Constant test expressions
[[ -e * .mpg ]] # Existence checks of globs
[[ $foo == 0 ]] # Always true due to missing spaces
[[ -n " $foo " ]] # Always true due to literals
[[ $foo =~ " fo+ " ]] # Quoted regex in =~
[ foo =~ re ] # Unsupported [ ] operators
[ $1 -eq " shellcheck " ] # Numerical comparison of strings
[ $n && $m ] # && in [ .. ]
[ grep -q foo file ] # Command without $(..)
[[ " $$ file " == * .jpg ]] # Comparisons that can't succeed
(( 1 - lt 2 )) # Using test operators in ((..))
[ x ] & [ y ] | [ z ] # Accidental backgrounding and piping
ShellCheck dapat mengenali kejadian di mana perintah digunakan secara tidak benar:
grep ' *foo* ' file # Globs in regex contexts
find . -exec foo {} && bar {} ; # Prematurely terminated find -exec
sudo echo ' Var=42 ' > /etc/profile # Redirecting sudo
time --format=%s sleep 10 # Passing time(1) flags to time builtin
while read h ; do ssh " $h " uptime # Commands eating while loop input
alias archive= ' mv $1 /backup ' # Defining aliases with arguments
tr -cd ' [a-zA-Z0-9] ' # [] around ranges in tr
exec foo ; echo " Done! " # Misused 'exec'
find -name * .bak -o -name * ~ -delete # Implicit precedence in find
# find . -exec foo > bar ; # Redirections in find
f () { whoami ; }; sudo f # External use of internal functions
ShellCheck mengenali banyak kesalahan sintaksis pemula yang umum:
var = 42 # Spaces around = in assignments
$foo =42 # $ in assignments
for $var in * ; do ... # $ in for loop variables
var $n = " Hello " # Wrong indirect assignment
echo ${var $n } # Wrong indirect reference
var=(1, 2, 3) # Comma separated arrays
array=( [index] = value ) # Incorrect index initialization
echo $var [14] # Missing {} in array references
echo " Argument 10 is $1 0 " # Positional parameter misreference
if $( myfunction ) ; then .. ; fi # Wrapping commands in $()
else if othercondition ; then .. # Using 'else if'
f ; f () { echo " hello world; } # Using function before definition
[ false ] # 'false' being true
if ( -f file ) # Using (..) instead of test
ShellCheck dapat memberikan saran untuk meningkatkan gaya:
[[ -z $( find /tmp | grep mpg ) ]] # Use grep -q instead
a >> log ; b >> log ; c >> log # Use a redirection block instead
echo " The time is ` date ` " # Use $() instead
cd dir ; process * ; cd .. ; # Use subshells instead
echo $[1+2] # Use standard $((..)) instead of old $[]
echo $(( $RANDOM % 6 )) # Don't use $ on variables in $((..))
echo " $( date ) " # Useless use of echo
cat file | grep foo # Useless use of cat
ShellCheck dapat mengenali masalah terkait data dan pengetikan:
args= " $@ " # Assigning arrays to strings
files=(foo bar) ; echo " $files " # Referencing arrays as strings
declare -A arr=(foo bar) # Associative arrays without index
printf " %sn " " Arguments: $@ . " # Concatenating strings and arrays
[[ $# > 2 ]] # Comparing numbers as strings
var=World ; echo " Hello " var # Unused lowercase variables
echo " Hello $name " # Unassigned lowercase variables
cmd | read bar ; echo $bar # Assignments in subshells
cat foo | cp bar # Piping to commands that don't read
printf ' %s: %sn ' foo # Mismatches in printf argument count
eval " ${array[@]} " # Lost word boundaries in array eval
for i in " ${x[@]} " ; do ${x[$i]} # Using array value as key
ShellCheck dapat memberikan saran untuk meningkatkan ketahanan skrip:
rm -rf " $STEAMROOT / " * # Catastrophic rm
touch ./-l ; ls * # Globs that could become options
find . -exec sh -c ' a && b {} ' ; # Find -exec shell injection
printf " Hello $name " # Variables in printf format
for f in $( ls * .txt ) ; do # Iterating over ls output
export MYVAR= $( cmd ) # Masked exit codes
case $version in 2. * ) : ;; 2.6. * ) # Shadowed case branches
ShellCheck akan memperingatkan ketika menggunakan fitur yang tidak didukung oleh Shebang. Misalnya, jika Anda menyetel shebang ke #!/bin/sh
, ShellCheck akan memperingatkan tentang masalah portabilitas yang mirip dengan checkbashisms
:
echo {1.. $n } # Works in ksh, but not bash/dash/sh
echo {1..10} # Works in ksh and bash, but not dash/sh
echo -n 42 # Works in ksh, bash and dash, undefined in sh
expr match str regex # Unportable alias for `expr str : regex`
trap ' exit 42 ' sigint # Unportable signal spec
cmd & > file # Unportable redirection operator
read foo < /dev/tcp/host/22 # Unportable intercepted files
foo-bar () { .. ; } # Undefined/unsupported function name
[ $UID = 0 ] # Variable undefined in dash/sh
local var=value # local is undefined in sh
time sleep 1 | sleep 5 # Undefined uses of 'time'
ShellCheck mengenali sejumlah masalah lain:
PS1= ' e[0;32m$e[0m ' # PS1 colors not in [..]
PATH= " $PATH :~/bin " # Literal tilde in $PATH
rm “file” # Unicode quotes
echo " Hello world " # Carriage return / DOS line endings
echo hello # Trailing spaces after
var=42 echo $var # Expansion of inlined environment
! # bin/bash -x -e # Common shebang errors
echo $(( n / 180 * 100 )) # Unnecessary loss of precision
ls * [:digit:].txt # Bad character class globs
sed ' s/foo/bar/ ' file > file # Redirecting to input
var2= $var2 # Variable assigned to itself
[ x $var = xval ] # Antiquated x-comparisons
ls () { ls -l " $@ " ; } # Infinitely recursive wrapper
alias ls= ' ls -l ' ; ls foo # Alias used before it takes effect
for x ; do for x ; do # Nested loop uses same variable
while getopts " a " f ; do case $f in " b " ) # Unhandled getopts flags
Pada awalnya Anda seperti "shellcheck itu luar biasa" tetapi kemudian Anda seperti "apakah kita masih menggunakan bash"
Alexander Tarasikov, melalui Twitter
Masalah dapat diabaikan melalui variabel lingkungan, baris perintah, secara individual atau global dalam file:
https://github.com/koalaman/shellcheck/wiki/Ignore
Silakan gunakan pelacak masalah GitHub untuk bug atau saran fitur apa pun:
https://github.com/koalaman/shellcheck/issues
Silakan kirimkan tambalan ke kode atau dokumentasi sebagai permintaan penarikan GitHub! Lihat DevGuide di ShellCheck Wiki.
Kontribusi harus dilisensikan di bawah GNU GPLv3. Kontributor memegang hak cipta.
ShellCheck dilisensikan di bawah Lisensi Publik Umum GNU, v3. Salinan lisensi ini disertakan dalam file LISENSI.
Hak Cipta 2012-2019, Vidar 'koala_man' Holen dan kontributor.
Selamat ShellChecking!