เป็นไปได้หรือไม่ที่จะตรวจสอบไวยากรณ์ของ bash script โดยไม่ต้องดำเนินการ?
ใช้ Perl, perl -c 'script name'
ฉันสามารถเรียกใช้ มีคำสั่งใด ๆ ที่เทียบเท่าสำหรับสคริปต์ทุบตีหรือไม่?
เป็นไปได้หรือไม่ที่จะตรวจสอบไวยากรณ์ของ bash script โดยไม่ต้องดำเนินการ?
ใช้ Perl, perl -c 'script name'
ฉันสามารถเรียกใช้ มีคำสั่งใด ๆ ที่เทียบเท่าสำหรับสคริปต์ทุบตีหรือไม่?
คำตอบ:
bash -n scriptname
บางทีอาจจะเป็นข้อแม้ชัดเจน: นี้ไวยากรณ์ตรวจสอบ แต่จะไม่ตรวจสอบว่าทุบตีสคริปต์พยายามของคุณเพื่อดำเนินการคำสั่งที่ไม่อยู่ในเส้นทางของคุณเช่นแทนech hello
echo hello
set
ทำ
if ["$var" == "string" ]
แทนif [ "$var" == "string" ]
type [
พูดว่า "[เป็นเชลล์ในตัว" ท้ายที่สุดจะมอบสิทธิ์ให้กับtest
โปรแกรม แต่คาดว่าจะมีวงเล็บเหลี่ยมปิดเช่นกัน ดังนั้นมันก็เหมือนif test"$var"
ซึ่งไม่ใช่สิ่งที่ผู้เขียนหมายถึง แต่ถูกต้องตามหลักไวยากรณ์ (พูดว่า $ var มีค่าเป็น "a" จากนั้นเราจะเห็น "bash: testa: command not found") ประเด็นก็คือว่าวากยสัมพันธ์ไม่มีที่ขาดหายไป
[
จะเรียกเฉพาะในกรณีนี้หาก$var
เกิดขึ้นจะขยายไปยังสตริงที่ว่างเปล่า หาก$var
ขยายไปยังสตริงที่ไม่ว่าง[
จะถูกต่อกับสตริงนั้นและถูกตีความเป็นชื่อคำสั่ง (ไม่ใช่ชื่อฟังก์ชัน ) โดย Bash และใช่ว่าจะถูกต้องตามหลักไวยากรณ์แต่ตามที่คุณระบุไว้ชัดเจนว่าไม่ใช่เจตนา หากคุณใช้[[
แทน[
แม้ว่า[[
จะเป็นคีย์เวิร์ดเชลล์(แทนที่จะเป็นบิวด์อิน) คุณจะได้รับผลลัพธ์เดียวกันเนื่องจากการต่อสตริงที่ไม่ได้ตั้งใจยังคงแทนที่คำสำคัญ
["$var"
เป็น ทางไวยากรณ์ของนิพจน์ชื่อคำสั่งที่ถูกต้อง ในทำนองเดียวกันราชสกุล==
และ"$string"
มีคำสั่งที่ถูกต้องข้อโต้แย้ง (โดยทั่วไปในตัว[
จะแยกกับคำสั่งไวยากรณ์ในขณะที่[[
- เป็นเปลือกคำหลัก - จะแยกแตกต่างกัน.) The builtin เปลือก[
ไม่ได้ มอบหมายไป " test
โปรแกรม" (ยูทิลิตี้ภายนอก): bash
, dash
, ksh
, zsh
ทุกคนมีในตัวรุ่นของทั้งสอง[
และtest
และจะไม่เรียกใช้งานยูทิลิตีภายนอก
เวลาเปลี่ยนแปลงทุกอย่าง นี่คือเว็บไซต์ที่ให้บริการตรวจสอบไวยากรณ์ออนไลน์สำหรับเชลล์สคริปต์
ฉันพบว่ามันมีประสิทธิภาพมากในการตรวจจับข้อผิดพลาดทั่วไป
ShellCheckเป็นการวิเคราะห์แบบคงที่และเป็นเครื่องมือในการทับหลังสำหรับสคริปต์ sh / bash มันมุ่งเน้นไปที่การจัดการข้อผิดพลาดทางไวยากรณ์ระดับเริ่มต้นและระดับกลางทั่วไปและข้อผิดพลาดที่เปลือกเพิ่งให้ข้อความแสดงข้อผิดพลาดที่คลุมเครือหรือพฤติกรรมแปลก ๆ แต่ก็ยังรายงานเกี่ยวกับปัญหาขั้นสูงเพิ่มเติมที่กรณีมุมอาจทำให้เกิดความล้มเหลวล่าช้า
ซอร์สโค้ดของ Haskell มีให้ที่ GitHub!
apt-get install shellcheck
trusty-backports
เชื่อถือแพคเกจนี้จะต้องมีการติดตั้งจาก
ฉันยังเปิดใช้งานตัวเลือก 'u' ในสคริปต์ทุบตีทุกครั้งที่ฉันเขียนเพื่อทำการตรวจสอบพิเศษ:
set -u
สิ่งนี้จะรายงานการใช้งานตัวแปรที่ไม่ได้กำหนดค่าเริ่มต้นเช่นในสคริปต์ 'check_init.sh' ต่อไปนี้
#!/bin/sh
set -u
message=hello
echo $mesage
เรียกใช้สคริปต์:
$ check_init.sh
จะรายงานสิ่งต่อไปนี้:
./check_init.shuty4]: mesage: ไม่ได้ตั้งค่าพารามิเตอร์
มีประโยชน์มากในการจับความผิดพลาด
set -u
แม้ว่าสิ่งนี้จะไม่ตอบคำถามจริงๆเพราะคุณต้องเรียกใช้สคริปต์เพื่อรับข้อความแสดงข้อผิดพลาด ไม่ได้bash -n check_init.sh
แสดงคำเตือนนั้น
sh -n script-name
เรียกใช้สิ่งนี้ หากมีข้อผิดพลาดทางไวยากรณ์ในสคริปต์ก็จะส่งกลับข้อผิดพลาดเดียวกัน หากไม่มีข้อผิดพลาดก็จะปรากฏขึ้นโดยไม่ให้ข้อความใด ๆ คุณสามารถตรวจสอบได้ทันทีโดยใช้echo $?
ซึ่งจะกลับมา0
ยืนยันว่าประสบความสำเร็จโดยไม่ผิดพลาดใด ๆ
มันทำงานได้ดีสำหรับฉัน ฉันวิ่งบน Linux OS, Bash Shell
sh -n
อาจจะไม่ตรวจสอบว่าสคริปต์นั้นเป็นสคริปต์ Bash ที่ถูกต้อง มันอาจให้ผลเชิงลบที่ผิดพลาด sh
เป็นตัวแปรเชลล์ Bourne บางตัวที่โดยปกติจะไม่ใช่ Bash ตัวอย่างเช่นใน Ubuntu Linux realpath -e $(command -v sh)
ให้ / bin / dash
ฉันตรวจสอบสคริปต์ bash ทั้งหมดใน dir ปัจจุบันเพื่อหาข้อผิดพลาดทางไวยากรณ์โดยไม่เรียกใช้โดยใช้find
เครื่องมือ:
ตัวอย่าง:
find . -name '*.sh' -exec bash -n {} \;
หากคุณต้องการใช้เป็นไฟล์เดียวให้แก้ไขสัญลักษณ์แทนด้วยชื่อไฟล์
มีปลั๊กอิน BashSupportสำหรับIntelliJ IDEAซึ่งตรวจสอบไวยากรณ์
.sh
หรือส่วนขยายอื่น ๆ ที่เกี่ยวข้องกับ Bash สคริปต์ซึ่งเป็นกรณีถ้าคุณสร้างสคริปต์โดยใช้เครื่องมือสร้างเทมเพลตเช่น ERB (จากนั้นจะจบด้วย.erb
) โปรดลงคะแนนให้youtrack.jetbrains.com/issue/IDEA-79574หากคุณต้องการแก้ไข!
หากคุณต้องการตัวแปรในการตรวจสอบความถูกต้องของไฟล์ทั้งหมดในไดเรกทอรี (git pre-commit hook, สคริปต์สร้าง lint) คุณสามารถตรวจจับเอาต์พุต stderr ของคำสั่ง "sh -n" หรือ "bash -n" (ดูอื่น ๆ คำตอบ) ในตัวแปรและมี "if / else" ตามนั้น
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
เปลี่ยน "sh" ด้วย "bash" ขึ้นอยู่กับความต้องการของคุณ