Bir bash betiği nasıl hata ayıklanır?


135

Bazı komut dosyalarında bash, hatalar ve beklenmeyen davranışlarla ilgili bazı sorunlar yaşıyorum. Sorunların nedenlerini araştırmak istiyorum, böylece düzeltmeleri uygulayabiliyorum. Daha fazla bilgi almak için bash için bir tür "hata ayıklama modu" açabilmemin bir yolu var mı?

Yanıtlar:


132

Hata ayıklama çıktısını görmek için bash komut dosyanızı başlatın bash -x ./script.shveya komut dosyanızı ekleyin set -x.


bash4.1 veya üstü ile ek :

Hata ayıklama çıktısını ayrı bir dosyaya yazmak istiyorsanız, bunu komut dosyasına ekleyin:

exec 5> debug_output.txt
BASH_XTRACEFD="5"

Bakınız: https://stackoverflow.com/a/25593226/3776858


Satır numaralarını görmek istiyorsanız şunu ekleyin:

PS4='$LINENO: '


loggerKomuta erişiminiz varsa, bunu zaman damgası, komut dosyası adı ve satır numarası ile syslog'unuz üzerinden hata ayıklama çıktısı yazmak için kullanabilirsiniz:

#!/bin/bash

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

# Place your code here

Sen seçeneğini kullanabilirsiniz -parasında loggerkendi günlük dosyası yerel syslog üzerinden çıktı yazmak için bireysel bir tesis ve düzeyini ayarlamak için komuta.


7
-v ayrıca yardımcı olabilir (yürütüldüklerinde her satırı yazdırır. -x ile birleştirilebilir). Ve ayrıca bkz: bashdb.sourceforge.net
Olivier Dulac

4
bir başka harika kaynak ise: shellcheck.net
Olivier Dulac

"Exec 5>" ne yapar?
aggsol

3
@aggsol: BASH_XTRACEFD="5"bash kullanıyorsanız set -x, dosya tanımlayıcısına 5 etkinleştirildiğinde oluşturulan iz çıktılarını yazar. exec 5> >(logger -t $0)Çıktıyı dosya tanıtıcısından 5 loggerkomutuna yönlendirir .
Cyrus

1
Sadece merak ediyorum, PS4'te satır numarası ve kabuk betiği yolunu veya adını bulabilir misiniz?
iloveretards

55

kullanma set -x

Ben her zaman set -xve kullanırım set +x. Ayrıntıları yukarı / aşağı çevirmek için onlarla ne olduğunu görmek istediğiniz alanları sarabilirsiniz.

#!/bin/bash

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

log4bash

Ayrıca geliştirme çalışması yaptıysanız ve log4j, log4perl, vb. Adlarını kullanan logger stillerini biliyorsanız, o zaman log4bash kullanmak isteyebilirsiniz .

alıntı

Kabul edelim - düz eski yankı sadece kesmiyor. log4bash, Bash betikleri için daha iyi bir kayıt tutma girişimidir.

Buradan Bash komut dosyalarınızda böyle şeyler yapabilirsiniz:

#!/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";

Bu tür çıktıda sonuçlanan:

    ss1

log4sh

Daha taşınabilir bir şeye ihtiyacınız olursa, daha da yaşlısı var log4sh. Benzer işler log4bash, burada bulabilirsiniz:


Ubuntu'da, komutu diğer dağıtımlardan veya OS X'den alias say="spd-say"taklit eden say
.bashrc'im var

1
set -vx, trap - trap read debug ile birlikte kullanılırsa iyi bir kombinasyon olur. Bu, satır adım adım
ilerlemenizi

34

Birçok dağıtımda kurulabilir bir paket olan bir bash debug , bashdb var . Bash'in yerleşik genişletilmiş hata ayıklama modunu ( shopt -s extdebug) kullanır. Gdb'ye çok benziyor; Bazı lezzet vermek için örnek bir oturum:

$ 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'de olduğu gibi, ifade neredeyse yürütülmek üzere olmadan önce gösterilir . Dolayısıyla, ifadenin yapmadan önce ne yapacağını görmek için değişkenleri inceleyebiliriz.

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

İstediğimiz bu değil! Parametre genişlemesine tekrar bakalım.

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

Tamam, işe yarıyor. newfDoğru değere ayarlayalım .

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

İyi görünüyor. Senaryoya devam et.

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

20

Çoğu Bourne tabanlı mermide bash gibi komut dosyalarında hata ayıklamanın standart yöntemi, betiğinizin en set -xüstüne yazmaktır . Bu, ne yapıldığını / yapıldığını ve tartışmaların nasıl değerlendirildiğini kısaca açıklayacaktır.

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

bu, tercüman veya iç komut dosyaları için yararlıdır. Örneğin:

$ 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

Yukarıda, bazı alıntılardan dolayı neden başarısız olduğunu görebiliyoruz.

Özelliği devre dışı bırakmak için, sadece yazın set +x.


13

Eclipse'i kullanma

Eclipse ve Shelled'in kombine ortamını, aşağıda bağlantılı "_DEBUG.sh" betiği ile kullanabilirsiniz.

Anahtarlama mermileri

Varsayılan olarak, Kabuklu geliştirme aracı /bin/dashtercüman olarak kullanır . Bunu /bin/bashweb'deki ve ortamımdaki kabuk örneklerinin çoğuyla daha iyi uyum sağlayacak şekilde değiştirdim .

NOT: Bunu aşağıdakilere giderek değiştirebilirsiniz: Pencere -> Tercih -> Kabuk Betiği -> Tercümanlar

Kurulum talimatları

Hata ayıklayıcı paketi, _DEBUG.shkomut dosyası hata ayıklamanız için temelde (readme.txt) komut dosyasını kullanma adımlarına sahiptir :

  1. Shell Script Projesi Oluştur: Dosya -> Yeni -> Diğer -> Shell Script -> Shell Script Proje Sihirbazı .
  2. Bash komut dosyası oluşturun: Dosya -> Yeni -> Dosya . Bu örnek için olacak script.sh. Uzantı ".sh" olmalı ve bir zorunluluktur.
  3. Dosyayı _DEBUG.shproje klasörüne kopyalayın.
  4. Aşağıdaki metni dosyanın üstüne yerleştirin script.sh:

    . _DEBUG.sh
  5. Dosya Microsoft Windows'da oluşturulduysa, Dosya -> Satır Sınırlayıcıları Kime -> Unix'i çalıştırdığınızdan emin olun .

  6. Bir hata ayıklama başlatma yapılandırması ayarlayın: Çalıştır -> Hata Ayıklama Yapılandırmaları -> Bash komut dosyası ... Burada ayarlanması gereken 2 alan vardır:

    a) "Bash betiği:" - Eclipse çalışma alanındaki hata ayıklama için Bash komut dosyasına giden yol.
    e) "Hata ayıklayıcı bağlantı noktası:" 33333

  7. Hata ayıklama perspektifine geçin. Hata ayıklama oturumunu başlatın. Başlatın script.shBash kabuğundan.

Bash hata ayıklama kullanıcı Arabirimi

görüntü tanımını buraya girin

Bu bash debugger , aşağıdaki gibi standart programlama hata ayıklayıcılarının tam özelliklerine sahiptir:

  • Kırılma Noktası geçişi
  • Tek Adım Adım İşlem
  • Step-in, Step-out, Step-over fonksiyonları ve alt rutinleri
  • Kod veya değişkenleri komut dosyası çalışırken herhangi bir noktada incelemek

Kabuklu (Kabuk Betiği Düzenleyici) IDE (Integrated Development Environment), betiğinizi yazarken bağlam kontrolü yapma, vurgulama ve girme işlemi yapma avantajına sahiptir. Doğru girintilemezse, burada hemen birçok hata / bayrak işaretleyebilirsiniz.

Öyleyse, bunun gibi başka IDE avantajları var :

  • TODO görev listesi
  • Mylyn Görevi
  • Yer imi listesi
  • Birden Çok Pencere Düzenleme
  • Çevrenin Uzaktan Paylaşımı

Serin ucu. Bash'in bu şekilde hata ayıklanabileceğini bilmek güzel.
slm

8

Son yıllarda harika bir kaynak ortaya çıktı: http://shellcheck.net

size, normal sinir bozucudan daha fazlasını gösterir ve bu, sinir bozucu, kapatılmamış tırnakları veya süslü parantezleri, vb. kolayca bulmanızı sağlar.

Net'e hassas bilgiler (ips, şifreler, vb.) Yapıştırmadığınızdan emin olun ... (özellikle http olduğu gibi, şifrelenmemiş) (shellcheck'in de indirebileceğine inanıyorum ama emin değilim)


6

basitçe kullanın:

#!/bin/bash -x

kabuk için aynı:

#!/bin/sh -x

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.