Mungkin peringatan yang jelas: ini memvalidasi sintaks tetapi tidak akan memeriksa apakah skrip bash Anda mencoba menjalankan perintah yang tidak ada di jalur Anda, seperti ech hellobukan echo hello.
Di manual bash, di bawah "SHELL BUILTIN COMMANDS / set", -n didokumentasikan, dan sebagai awal dari status manpage, bash mengartikan semua opsi karakter tunggal yang setberlaku.
ephemient
24
untuk menambah (bagi saya) peringatan yang tidak jelas, itu juga tidak akan menangkap kesalahan yang disebabkan oleh ruang yang hilang, if ["$var" == "string" ]bukanif [ "$var" == "string" ]
Brynjar
11
@ Brynjar Itu karena itu hanya memeriksa sintaksis. Braket terbuka bukan sintaks, itulah nama fungsi yang akan dijalankan. type [mengatakan "[adalah shell builtin". Ini akhirnya mendelegasikan ke testprogram, tetapi mengharapkan braket penutupan, juga. Jadi itu seperti if test"$var", yang bukan apa yang dimaksud penulis, tetapi secara sintaksis valid (katakanlah $ var memiliki nilai "a", maka kita akan melihat "bash: testa: command not found"). Intinya adalah bahwa secara sintaksis, tidak ada ruang yang hilang.
Joshua Cheek
2
@JoshuaCheek: Builtin [hanya dipanggil dalam kasus ini jika $varterjadi ekspansi ke string kosong . Jika $varmengembang ke non-kosong string [adalah concatenated dengan tali itu dan ditafsirkan sebagai perintah nama (tidak fungsi nama) oleh Bash, dan, ya, itu adalah sintaksis valid, tapi, seperti yang Anda negara, jelas tidak maksud. Jika Anda menggunakan [[alih-alih [, meskipun [[merupakan kata kunci shell (bukan builtin), Anda akan mendapatkan hasil yang sama, karena penggabungan string yang tidak diinginkan masih mengesampingkan pengenalan kata kunci.
mklement0
2
@ JoshuaCheek: Bash masih sintaksis - cek di sini: itu memeriksa sintaks pemanggilan perintah sederhana : ["$var"secara sintaksis ekspresi nama-perintah yang valid ; demikian pula, token ==dan argumen"$string" perintah yang valid . (Umumnya, builtin parsing dengan perintah sintaks, sedangkan - sebagai shell kata kunci - parsing berbeda.) Shell builtin tidak tidak mendelegasikan ke " Program" (utilitas eksternal): , , , semua memiliki builtin versi kedua dan[[[[testbashdashkshzsh[test, dan mereka tidak memanggil mitra utilitas eksternal mereka.
mklement0
127
Waktu mengubah segalanya. Berikut adalah situs web yang menyediakan sintaksis online untuk memeriksa skrip shell.
Saya menemukan itu sangat kuat mendeteksi kesalahan umum.
Tentang ShellCheck
ShellCheck adalah alat analisis dan linting statis untuk skrip sh / bash. Ini terutama berfokus pada penanganan tipikal tingkat kesalahan pemula dan menengah dan perangkap di mana shell hanya memberikan pesan kesalahan samar atau perilaku aneh, tetapi juga melaporkan beberapa masalah lebih lanjut di mana kasus sudut dapat menyebabkan kegagalan tertunda.
Tip yang bagus; di OSX Anda sekarang dapat juga menginstal CLI shellcheck.net, shellcheck, melalui Homebrew : brew install shellcheck.
mklement0
3
Juga di debian & teman-teman:apt-get install shellcheck
pria lain itu
Untuk Ubuntu terpercaya paket ini harus diinstal dari trusty-backports.
Peterino 4-15
Seperti disebutkan di atas, ketergantungan yang dapat dipercaya dibutuhkan, dan dapat menginstalnya seperti di bawah ini di ubuntu 14.04: sudo apt-get -f install, kemudian: sudo sudo apt-get install shellcheck
zhihong
Ini sangat berguna, tetapi tidak menggunakan parser Bash tapi miliknya sendiri. Dalam kebanyakan kasus ini cukup baik dan dapat mengidentifikasi masalah parsing dan lainnya, tetapi setidaknya ada satu kasus tepi (dan mungkin yang lain saya belum melihat) di mana ia tidak menguraikan dengan cara yang sama.
Daniel H
38
Saya juga mengaktifkan opsi 'u' pada setiap skrip bash yang saya tulis untuk melakukan beberapa pemeriksaan tambahan:
set-u
Ini akan melaporkan penggunaan variabel yang tidak diinisialisasi, seperti pada skrip berikut 'check_init.sh'
#!/bin/shset-u
message=hello
echo $mesage
Menjalankan skrip:
$ check_init.sh
Akan melaporkan sebagai berikut:
./check_init.sh[4]: mesage: Parameter tidak disetel.
saya mengatur flag-flag ini selalu dalam skrip bash saya, jika melewati ini, ada baiknya untuk "set -o errexit" "set -o nounset" "set -o pipefail"
μολὼν.λαβέ
1 untuk set -uwalaupun ini tidak benar-benar menjawab pertanyaan, karena Anda harus menjalankan skrip untuk mendapatkan pesan kesalahan. Bahkan tidak bash -n check_init.shmenunjukkan peringatan itu
rubo77
23
sh -n script-name
Jalankan ini. Jika ada kesalahan sintaksis dalam skrip, maka ia mengembalikan pesan kesalahan yang sama. Jika tidak ada kesalahan, maka itu keluar tanpa memberikan pesan apa pun. Anda dapat segera memeriksa dengan menggunakan echo $?, yang akan mengembalikan 0konfirmasi berhasil tanpa kesalahan.
Itu bekerja dengan baik untuk saya. Saya berlari di OS Linux, Bash Shell.
Meskipun tidak persis terkait dengan cek sintaks bash - menggunakan set -x dan set + x untuk debugging skrip lengkap atau bagian skrip cukup berguna
GuruM
Terima kasih untuk ini tidak tahu tidak tahu tentang -n tetapi yang saya inginkan adalah @GuruM> sh -x test.sh karena itu akan menampilkan output skrip yang
dihasilkan
1
Iya. Saya lupa menyebutkan bahwa Anda dapat melakukan hal berikut Pada baris perintah: 1) bash -x test.sh # ini menjalankan seluruh skrip dalam 'mode debug' 2) set + x; bash test.sh; set -x #setel mode debug hidup / mati sebelum / sesudah skrip dijalankan Dalam skrip: a) #! / bin / bash -x # tambahkan 'mode debug' di atas skrip b) set + x; kode; set -x #add 'mode debug' untuk setiap bagian skrip
GuruM
sh -nmungkin tidak akan memeriksa bahwa skrip tersebut adalah skrip Bash yang valid. Mungkin memberikan negatif palsu. shadalah beberapa varian shell Bourne yang biasanya bukan Bash. Misalnya di Ubuntu Linux realpath -e $(command -v sh)memberi / bin / dash
jarno
4
Saya benar-benar memeriksa semua skrip bash dalam direktori saat ini untuk mengetahui kesalahan sintaksis TANPA menjalankannya menggunakan findalat:
Contoh:
find . -name '*.sh' -exec bash -n {} \;
Jika Anda ingin menggunakannya untuk satu file, cukup edit wildcard dengan nama file tersebut.
Tapi itu tidak akan berfungsi jika file Anda tidak diakhiri dengan .shatau ekstensi lain yang terkait dengan skrip Bash, yang merupakan kasus jika Anda menghasilkan skrip menggunakan beberapa alat templating seperti ERB (kemudian berakhir dengan .erb). Silakan pilih youtrack.jetbrains.com/issue/IDEA-79574 jika Anda ingin memperbaikinya!
Greg Dubicki
1
Jika Anda perlu dalam variabel validitas semua file dalam direktori (git pre-commit hook, build skrip lint), Anda dapat menangkap output stderr dari perintah "sh -n" atau "bash -n" (lihat lainnya jawaban) dalam suatu variabel, dan memiliki "jika / lain" berdasarkan itu
bashErrLines=$(find bin/-type f -name '*.sh'-exec sh -n {} \; 2>&1>/dev/null)if["$bashErrLines"!=""];then# at least one sh file in the bin dir has a syntax error
echo $bashErrLines;
exit;fi
Ganti "sh" dengan "bash" tergantung kebutuhan Anda
Jawaban:
Mungkin peringatan yang jelas: ini memvalidasi sintaks tetapi tidak akan memeriksa apakah skrip bash Anda mencoba menjalankan perintah yang tidak ada di jalur Anda, seperti
ech hello
bukanecho hello
.sumber
set
berlaku.if ["$var" == "string" ]
bukanif [ "$var" == "string" ]
type [
mengatakan "[adalah shell builtin". Ini akhirnya mendelegasikan ketest
program, tetapi mengharapkan braket penutupan, juga. Jadi itu sepertiif test"$var"
, yang bukan apa yang dimaksud penulis, tetapi secara sintaksis valid (katakanlah $ var memiliki nilai "a", maka kita akan melihat "bash: testa: command not found"). Intinya adalah bahwa secara sintaksis, tidak ada ruang yang hilang.[
hanya dipanggil dalam kasus ini jika$var
terjadi ekspansi ke string kosong . Jika$var
mengembang ke non-kosong string[
adalah concatenated dengan tali itu dan ditafsirkan sebagai perintah nama (tidak fungsi nama) oleh Bash, dan, ya, itu adalah sintaksis valid, tapi, seperti yang Anda negara, jelas tidak maksud. Jika Anda menggunakan[[
alih-alih[
, meskipun[[
merupakan kata kunci shell (bukan builtin), Anda akan mendapatkan hasil yang sama, karena penggabungan string yang tidak diinginkan masih mengesampingkan pengenalan kata kunci.["$var"
secara sintaksis ekspresi nama-perintah yang valid ; demikian pula, token==
dan argumen"$string"
perintah yang valid . (Umumnya, builtin parsing dengan perintah sintaks, sedangkan - sebagai shell kata kunci - parsing berbeda.) Shell builtin tidak tidak mendelegasikan ke " Program" (utilitas eksternal): , , , semua memiliki builtin versi kedua dan[
[[
[
test
bash
dash
ksh
zsh
[
test
, dan mereka tidak memanggil mitra utilitas eksternal mereka.Waktu mengubah segalanya. Berikut adalah situs web yang menyediakan sintaksis online untuk memeriksa skrip shell.
Saya menemukan itu sangat kuat mendeteksi kesalahan umum.
Tentang ShellCheck
ShellCheck adalah alat analisis dan linting statis untuk skrip sh / bash. Ini terutama berfokus pada penanganan tipikal tingkat kesalahan pemula dan menengah dan perangkap di mana shell hanya memberikan pesan kesalahan samar atau perilaku aneh, tetapi juga melaporkan beberapa masalah lebih lanjut di mana kasus sudut dapat menyebabkan kegagalan tertunda.
Kode sumber Haskell tersedia di GitHub!
sumber
shellcheck
, melalui Homebrew :brew install shellcheck
.apt-get install shellcheck
trusty-backports
.Saya juga mengaktifkan opsi 'u' pada setiap skrip bash yang saya tulis untuk melakukan beberapa pemeriksaan tambahan:
Ini akan melaporkan penggunaan variabel yang tidak diinisialisasi, seperti pada skrip berikut 'check_init.sh'
Menjalankan skrip:
Akan melaporkan sebagai berikut:
Sangat berguna untuk menangkap kesalahan ketik
sumber
set -u
walaupun ini tidak benar-benar menjawab pertanyaan, karena Anda harus menjalankan skrip untuk mendapatkan pesan kesalahan. Bahkan tidakbash -n check_init.sh
menunjukkan peringatan ituJalankan ini. Jika ada kesalahan sintaksis dalam skrip, maka ia mengembalikan pesan kesalahan yang sama. Jika tidak ada kesalahan, maka itu keluar tanpa memberikan pesan apa pun. Anda dapat segera memeriksa dengan menggunakan
echo $?
, yang akan mengembalikan0
konfirmasi berhasil tanpa kesalahan.Itu bekerja dengan baik untuk saya. Saya berlari di OS Linux, Bash Shell.
sumber
sh -n
mungkin tidak akan memeriksa bahwa skrip tersebut adalah skrip Bash yang valid. Mungkin memberikan negatif palsu.sh
adalah beberapa varian shell Bourne yang biasanya bukan Bash. Misalnya di Ubuntu Linuxrealpath -e $(command -v sh)
memberi / bin / dashSaya benar-benar memeriksa semua skrip bash dalam direktori saat ini untuk mengetahui kesalahan sintaksis TANPA menjalankannya menggunakan
find
alat:Contoh:
find . -name '*.sh' -exec bash -n {} \;
Jika Anda ingin menggunakannya untuk satu file, cukup edit wildcard dengan nama file tersebut.
sumber
perintah nol [titik dua] juga berguna saat debugging untuk melihat nilai variabel
sumber
set -x
menunjukkan setiap baris sebelum dieksekusiAda plugin BashSupport untuk IntelliJ IDEA yang memeriksa sintaksis.
sumber
.sh
atau ekstensi lain yang terkait dengan skrip Bash, yang merupakan kasus jika Anda menghasilkan skrip menggunakan beberapa alat templating seperti ERB (kemudian berakhir dengan.erb
). Silakan pilih youtrack.jetbrains.com/issue/IDEA-79574 jika Anda ingin memperbaikinya!Jika Anda perlu dalam variabel validitas semua file dalam direktori (git pre-commit hook, build skrip lint), Anda dapat menangkap output stderr dari perintah "sh -n" atau "bash -n" (lihat lainnya jawaban) dalam suatu variabel, dan memiliki "jika / lain" berdasarkan itu
Ganti "sh" dengan "bash" tergantung kebutuhan Anda
sumber