कैसे एक बैश स्क्रिप्ट डिबग करने के लिए?


135

त्रुटियों और अप्रत्याशित व्यवहारों के बारे में मुझे कुछ लिपियों में कुछ समस्याएँ हैं। मैं समस्याओं के कारणों की जांच करना चाहूंगा ताकि मैं सुधार लागू कर सकूं। क्या कोई ऐसा तरीका है जिससे मैं अधिक जानकारी प्राप्त करने के लिए बैश के लिए "डिबग-मोड" को बदल सकता हूं?

जवाबों:


132

डीबग आउटपुट देखने के लिए bash -x ./script.shअपनी स्क्रिप्ट के साथ अपनी स्क्रिप्ट शुरू करें या जोड़ें set -x


bash4.1 या बाद वाले अतिरिक्त :

यदि आप डिबग आउटपुट को एक अलग फ़ाइल में लिखना चाहते हैं, तो इसे अपनी स्क्रिप्ट में जोड़ें:

exec 5> debug_output.txt
BASH_XTRACEFD="5"

देखें: https://stackoverflow.com/a/25593226/3776858


यदि आप पंक्ति संख्याएँ देखना चाहते हैं, तो इसे जोड़ें:

PS4='$LINENO: '


यदि आपके पास loggerकमांड का उपयोग है तो आप इसका उपयोग डिबग आउटपुट को लिखने के लिए टाइमस्टैम्प, स्क्रिप्ट नाम और लाइन कोड के साथ कर सकते हैं:

#!/bin/bash

exec 5> >(logger -t $0)
BASH_XTRACEFD="5"
PS4='$LINENO: '
set -x

# Place your code here

आप व्यक्तिगत लॉग-इन के लिए आउटपुट लिखने के लिए कमांड के विकल्प -pका उपयोग कर सकते हैं loggerऔर आउटपुट को स्थानीय लॉग-इन के माध्यम से लिख सकते हैं।


7
-v भी मदद कर सकता है (प्रत्येक पंक्ति को प्रिंट करता है क्योंकि वे निष्पादित होते हैं। -x के साथ जोड़ा जा सकता है)। और यह भी देखें: bashdb.sourceforge.net
ओलिवियर

4
एक और अद्भुत संसाधन है: shellcheck.net
ओलिवियर

"5>" क्या करता है?
Aggsol

3
@aggsol: आप का उपयोग करते हैं BASH_XTRACEFD="5"ट्रेस उत्पादन उत्पन्न होती है जब लिखते हैं बैश set -xके लिए सक्षम किया गया है वर्णनकर्ता फाइल 5. exec 5> >(logger -t $0)करने के लिए फ़ाइल वर्णनकर्ता 5 से उत्पादन पुनर्निर्देश loggerआदेश।
सायरस

1
बस आप सोच सकते हैं कि आपको पीएस 4 में लाइन नंबर और शेल स्क्रिप्ट पथ या नाम मिल सकता है?
इलवरटर्ड्स

55

का उपयोग करते हुए set -x

मैं हमेशा का उपयोग set -xऔर set +x। आप उन क्षेत्रों को लपेट सकते हैं जिन्हें आप देखना चाहते हैं कि उनके साथ क्रियात्मकता को ऊपर / नीचे करने के लिए क्या हो रहा है।

#!/bin/bash

set -x
..code to debug...
set +x

log4bash

इसके अलावा अगर आपने विकास कार्य किया है और लॉग 4j, log4perl आदि नामों से जाने वाले लॉगर की शैली से परिचित हैं, तो आप लॉग 4bash का उपयोग करना चाहते हैं ।

अंश

चलो इसका सामना करते हैं - सादे पुराने गूंज बस इसे काट नहीं करता है। log4bash बैश स्क्रिप्ट के लिए बेहतर लॉगिंग करने का प्रयास है (यानी बैश चूसना में लॉगिंग कम करें)।

वहां से आप अपनी बैश स्क्रिप्ट में इस तरह की चीजें कर सकते हैं:

#!/usr/bin/env bash
source log4bash.sh

log "This is regular log message... log and log_info do the same thing";

log_warning "Luke ... you turned off your targeting computer";
log_info "I have you now!";
log_success "You're all clear kid, now let's blow this thing and go home.";
log_error "One thing's for sure, we're all gonna be a lot thinner.";

# If you have figlet installed -- you'll see some big letters on the screen!
log_captains "What was in the captain's toilet?";

# If you have the "say" command (e.g. on a Mac)
log_speak "Resistance is futile";

इस प्रकार के आउटपुट में परिणाम:

    SS1

log4sh

यदि आपको कुछ अधिक पोर्टेबल की आवश्यकता है तो पुराने भी हैं log4shlog4bashयहाँ उपलब्ध के समान कार्य करता है:


उबंटू में, मेरे पास alias say="spd-say".bashrc, जो sayअन्य डिस्ट्रोस या OS X से कमांड का अनुकरण करता है।
Doorknob

1
set -vx एक अच्छा संयोजन होगा यदि ट्रैप - ट्रैप डीबग के साथ प्रयोग किया जाए। यह आपको लाइन से लाइन पर कदम रखने और परिणाम देखने की अनुमति देता है
मैग्नस मेलविन

34

एक बैश डीबगर, बैशब है , जो कई डिस्ट्रो पर एक संस्थापित पैकेज है। यह बैश के अंतर्निहित विस्तारित डिबगिंग मोड ( shopt -s extdebug) का उपयोग करता है । यह gdb की तरह बहुत कुछ दिखता है; यहाँ कुछ स्वाद देने के लिए एक नमूना सत्र है:

$ ls
1st.JPG  2ndJPG.JPG
$ cat ../foo.sh
for f in *.JPG
do
  newf=${f/JPG/jpg}
  mv $f $newf
done
$ bashdb ../foo.sh
(foo.sh:1):
1:      for f in *.JPG
bashdb<0> next
(foo.sh:3):
3:        newf=${f/JPG/jpg}
bashdb<1> next
(foo.sh:4):
4:        mv $f $newf

जैसा कि gdb में, स्टेटमेंट निष्पादित होने से ठीक पहले दिखाया जाता है। इसलिए हम वेरिएबल्स की जांच कर सकते हैं कि यह देखने से पहले कि स्टेटमेंट क्या करेगा।

bashdb<2> print $f $newf
1st.JPG 1st.jpg
bashdb<3> next
(foo.sh:1):
1:      for f in *.JPG
bashdb<4> next
(foo.sh:3):
3:        newf=${f/JPG/jpg}
bashdb<5> next
(foo.sh:4):
4:        mv $f $newf
bashdb<6> print $f $newf
2ndJPG.JPG 2ndjpg.JPG

यही हम नहीं चाहते हैं! आइए पैरामीटर विस्तार को फिर से देखें।

bashdb<7> print $f ${f/JPG/jpg}
2ndJPG.JPG 2ndjpg.JPG
bashdb<8> print $f ${f/JPG$/jpg}
2ndJPG.JPG 2ndJPG.JPG
bashdb<9> print $f ${f/%JPG/jpg}
2ndJPG.JPG 2ndJPG.jpg

ठीक है, वह काम करता है। चलो newfसही मूल्य पर सेट करें।

bashdb<10> eval newf=${f/%JPG/jpg}
$? is 0
bashdb<11> print $f $newf
2ndJPG.JPG 2ndJPG.jpg

अछा लगता है। स्क्रिप्ट जारी रखें।

bashdb<12> next
Debugged program terminated normally. Use q to quit or R to restart.
$ ls
1st.jpg  2ndJPG.jpg

20

अधिकांश बॉर्न-आधारित गोले में स्क्रिप्ट को डीबग करने का मानक तरीका, जैसे बैश set -xआपकी स्क्रिप्ट के शीर्ष पर लिखना है । यह क्या किया / निष्पादित किया जा रहा है, और कैसे तर्कों का मूल्यांकन किया जाता है, इसके बारे में अधिक वाचालता बना देगा।

-x  Print commands and their arguments as they are executed.

यह या तो इंटरप्रेटर या स्क्रिप्ट्स के लिए उपयोगी है। उदाहरण के लिए:

$ find "$fileloc" -type f -prune "$filename" -print
+ find /var/adm/logs/morelogs -type f -prune '-name *.user' -print
find: unknown predicate '-name *.user'
$ find "$fileloc" -type f -prune $filename -print
+ find /var/adm/logs/morelogs -type f -prune -name '*.user' -print
find: '/var/adm/logs/morelogs': No such file or directory

ऊपर हम देख सकते हैं कि कुछ एकल उद्धरणों के कारण खोज विफल क्यों हो रही है।

सुविधा को निष्क्रिय करने के लिए, बस टाइप करें set +x


13

ग्रहण का उपयोग करना

आप नीचे दिए गए "_DEBUG.sh" स्क्रिप्ट के साथ ग्रहण और शैल के संयुक्त वातावरण का उपयोग कर सकते हैं।

स्विचिंग गोले

डिफ़ॉल्ट रूप से शेल्ड विकास उपकरण /bin/dashदुभाषिया के रूप में उपयोग करता है । मैंने इसे /bin/bashवेब और मेरे पर्यावरण पर अधिकांश शेल उदाहरणों के साथ बेहतर संगतता के लिए बदल दिया ।

नोट: आप इसे विंडो : - वरीयता -> शेल स्क्रिप्ट -> व्याख्याकारों में जाकर बदल सकते हैं

सेटअप निर्देश

डीबगर पैकेज में _DEBUG.shआपकी स्क्रिप्ट डीबगिंग के लिए स्क्रिप्ट का उपयोग करने के चरण हैं जो मूल रूप से (readme.txt) है:

  1. शेल स्क्रिप्ट प्रोजेक्ट बनाएँ: फ़ाइल -> नया -> अन्य -> शेल स्क्रिप्ट -> शेल स्क्रिप्ट प्रोजेक्ट विज़ार्ड
  2. एक बैश स्क्रिप्ट फ़ाइल बनाएँ: फ़ाइल -> नया -> फ़ाइल । इस उदाहरण के लिए, यह होगा script.sh। एक्सटेंशन ".sh" होना चाहिए और एक होना चाहिए।
  3. फ़ाइल _DEBUG.shको प्रोजेक्ट फ़ोल्डर में कॉपी करें ।
  4. फ़ाइल के शीर्ष पर निम्न पाठ डालें script.sh:

    . _DEBUG.sh
  5. यदि फ़ाइल Microsoft Windows में बनाई गई है, तो फ़ाइल को निष्पादित करना सुनिश्चित करें -> लाइन डिलाईमीटर को -> यूनिक्स में कनवर्ट करें

  6. डिबग लॉन्च कॉन्फ़िगरेशन सेट करें: रन -> डिबग कॉन्फ़िगरेशन -> बैश स्क्रिप्ट ... यहां सेट करने के लिए 2 फ़ील्ड हैं:

    a) "बैश स्क्रिप्ट:" - ईश के कार्यक्षेत्र में पथ बैश स्क्रिप्ट को डीबग करने के लिए।
    ई) "डिबगर पोर्ट:" 33333

  7. डीबग परिप्रेक्ष्य में स्विच करें। डिबगिंग सत्र प्रारंभ करें। script.shबैश शेल से लॉन्च करें ।

बैश डिबग यूआई

यहां छवि विवरण दर्ज करें

इस बैश डीबगर में मानक प्रोग्रामिंग डिबगर्स की पूरी विशेषताएं हैं जैसे:

  • ब्रेक प्वाइंट टॉगल
  • एकल चरण-दर-चरण ऑपरेशन
  • स्टेप-इन, स्टेप-आउट, स्टेप-ओवर फ़ंक्शन और उप-रूटीन
  • स्क्रिप्ट चलाते समय किसी भी बिंदु पर कोड या चर की जांच करना

शेल्ड (शेल स्क्रिप्ट एडिटर) आईडीई (इंटीग्रेटेड डेवलपमेंट एनवायरनमेंट) के पास अपनी स्क्रिप्ट लिखते समय परफॉर्मेंस चेकिंग, हाइलाइटिंग और इंडेंट करने का एक अतिरिक्त बोनस है। यदि यह सही ढंग से नहीं जाता है, तो आप तुरंत वहां कई त्रुटियों को चिह्नित / स्थानीय कर सकते हैं।

फिर अन्य आईडीई लाभ हैं जैसे:

  • TODO कार्य सूची
  • माइलिन टास्क
  • बुकमार्क सूची
  • एकाधिक विंडो संपादन
  • पर्यावरण का रिमोट शेयरिंग

शांत टिप। यह जानकर अच्छा लगा कि बैश को इस तरह डिबेट किया जा सकता है।
slm

8

हाल के वर्षों में एक अद्भुत संसाधन दिखाई दिया: http://shellcheck.net

यह आपको नियमित रूप से होने वाली मार-काट से अधिक दिखाता है, जिससे व्यक्ति आसानी से उन अजीबोगरीब उद्धरणों या घुंघराले कोष्ठक आदि को ढूंढ सकता है।

बस सुनिश्चित करें कि आप नेट पर संवेदनशील infos (ips, पासवर्ड, आदि) पेस्ट नहीं करते हैं ... (विशेष रूप से यह http, अनएन्क्रिप्टेड है) (मेरा मानना ​​है कि शेलचेक भी डाउनलोड करने के लिए उपलब्ध है, लेकिन मुझे यकीन नहीं है)


6

आजकल, वीएस कोड बैश डिबग है।

https://marketplace.visualstudio.com/items?itemName=rogalmic.bash-debug

इसमें 'स्टेप इन / आउट / ओवर' है और प्रत्येक वेरिएबल का मान भी दिखाता है।

वी.एस. कोड बैश डिबग स्क्रीनशॉट


यह उत्तर प्रश्न को सही संदर्भ में संबोधित नहीं करता है; कमांड लाइन संभालने के बाद से IDE का उल्लेख नहीं किया गया था
qodeninja

5

बस उपयोग करें:

#!/bin/bash -x

शेल के लिए समान:

#!/bin/sh -x
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.