วิธีดำเนินการ bash script ทีละบรรทัด?


97

ถ้าฉันป้อนตัวเลือกbash -xมันจะแสดงทุกบรรทัด แต่สคริปต์จะดำเนินการตามปกติ

ฉันจะดำเนินการทีละบรรทัดได้อย่างไร? กว่าฉันจะเห็นว่ามันทำถูกต้องหรือฉันยกเลิกและแก้ไข ใส่เอฟเฟกต์เดียวกันreadในทุกบรรทัด


1
อาจจะกว้างกว่านี้ให้ดูstackoverflow.com/questions/951336/how-to-debug-a-bash-script/…
tripleee

คำตอบ:


130

คุณไม่จำเป็นต้องอ่านทุกบรรทัดเพียงแค่เพิ่มกับดักดังต่อไปนี้ลงในสคริปต์ทุบตีของคุณมันมีผลตามที่คุณต้องการเช่น

#!/usr/bin/env bash
set -x
trap read debug

< YOUR CODE HERE >

ใช้งานได้เพียงทดสอบด้วย bash v4.2.8 และ v3.2.25


รุ่นปรับปรุง

หากสคริปต์ของคุณกำลังอ่านเนื้อหาจากไฟล์รายการข้างต้นจะไม่ทำงาน วิธีแก้ปัญหาอาจมีลักษณะดังตัวอย่างต่อไปนี้

#!/usr/bin/env bash
echo "Press CTRL+C to proceed."
trap "pkill -f 'sleep 1h'" INT
trap "set +x ; sleep 1h ; set -x" DEBUG

< YOUR CODE HERE >

หากต้องการหยุดสคริปต์คุณจะต้องฆ่ามันจากเชลล์อื่นในกรณีนี้


ทางเลือก 1

หากคุณต้องการรอสักครู่ก่อนดำเนินการคำสั่งถัดไปในสคริปต์ของคุณตัวอย่างต่อไปนี้อาจเหมาะกับคุณ

#!/usr/bin/env bash
trap "set +x; sleep 5; set -x" DEBUG

< YOUR CODE HERE >

ฉันกำลังเพิ่ม set + x และ set -x ภายในคำสั่ง trap เพื่อให้เอาต์พุตอ่านได้ง่ายขึ้น


2
แล้วคุณจะก้าวไปยังบรรทัดถัดไปอย่างไร (เรียกใช้คำสั่งถัดไป)?
David Doria

2
มันดักอ่านทุกคำสั่ง สิ่งเดียวที่คุณต้องทำคือกดกลับเพื่อไปที่คำสั่งถัดไป
organic-mashup

1
หากคุณมีบรรทัดคำสั่งเช่นนี้ "while read line; do echo $ line; done <somefile" วิธีนั้นใช้ไม่ได้เพราะ "trap read DEBUG" อ่านบรรทัดจาก somefile
mug896

3
คุณจะทำให้มันหยุดได้อย่างไร? หลังจากที่ฉันก้าวผ่านสคริปต์ไปจนจบเชลล์จะทำหน้าที่เหมือนสคริปต์ยังคงทำงานอยู่
slashdottir

1
เปลี่ยนเป็นtrap 'read -u1' debugเพื่อลบล้างปัญหาการเปลี่ยนเส้นทางการอ่านไฟล์
user3132194

23

บางทีBASH Debuggerอาจเป็นสิ่งที่เหมาะสำหรับคุณ


3
นี่เป็นทางออกที่ดีที่สุดจริงๆ อนุญาตให้ดูบรรทัดก่อนที่จะรัน (และอื่น ๆ อีกมากมาย) ในระบบส่วนใหญ่สามารถติดตั้งapt-get install bashdbได้ จากนั้นคุณก็ต้องวิ่งbashdb your_command.shพิมพ์stepแล้วกดกลับรถหลังจากนั้น
studgeek

1
@studgeek ไม่มีใน Redhat / CentOS เป็นต้นดังนั้นฉันจะไม่เรียกสิ่งนั้นว่า "ระบบส่วนใหญ่"
Sajuuk

@Sajuuk มันอาจจะไม่ได้รับการบรรจุแต่ก็อย่างที่มีอยู่
Charles Duffy

macOS:brew install bashdb
boweeb

@CharlesDuffy: มันไม่ได้อยู่ใน repos เริ่มต้นของ Ubuntu เช่นกัน
Dan Dascalescu

3

หากสคริปต์ทุบตีของคุณเป็นคำสั่งปิดหนึ่งคำที่คุณต้องการเรียกใช้ทีละรายการคุณสามารถทำสิ่งนี้ได้ซึ่งจะรันคำสั่งทีละคำสั่งเมื่อคุณเพิ่มตัวแปรLNตามหมายเลขบรรทัดที่คุณต้องการเรียกใช้ . สิ่งนี้ช่วยให้คุณสามารถเรียกใช้คำสั่งสุดท้ายอีกครั้งอย่างง่ายสุด ๆ จากนั้นคุณเพียงแค่เพิ่มตัวแปรเพื่อไปที่คำสั่งถัดไป

สมมติว่าคำสั่งของคุณอยู่ในไฟล์ "it.sh" ให้เรียกใช้คำสั่งต่อไปนี้ทีละรายการ

$ cat it.sh
echo "hi there"
date
ls -la /etc/passwd

$ $(LN=1 && cat it.sh | head -n$LN | tail -n1)
"hi there"

$ $(LN=2 && cat it.sh | head -n$LN | tail -n1)
Wed Feb 28 10:58:52 AST 2018

$ $(LN=3 && cat it.sh | head -n$LN | tail -n1)
-rw-r--r-- 1 root wheel 6774 Oct 2 21:29 /etc/passwd


1

xargs:สามารถกรองเส้น

cat .bashrc | xargs -0 -l -d \\n bash
  • -0 ถือว่าเป็นอินพุตดิบ (ไม่มีการหลบหนี)
  • -l แยกแต่ละบรรทัด (ไม่ใช่ตามค่าเริ่มต้นสำหรับการแสดง)
  • -d \\ n ตัวคั่นบรรทัด
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.