Bir bash işlevinin tanımlandığı dosyayı nasıl bulabilirim?


33

Bir bash işlevinin tanımlandığı dosyayı nasıl bulacağımı çözemiyorum ( __git_ps1benim durumumda).

Ben deneyler declare, type, which, ama hiçbir şey bana kaynak dosyasını söyler. declareDosya adını ve satır numarasını yazdırabilecek bir yere okudum , ancak nasıl açıklanamadığı açıklandı. helpSayfa declareya da söylemez.

Bu bilgiyi nasıl alabilirim?


İşlevin dosyası için yol dahil değilse $PATH, o zaman typeiş olmaz. Sadece findveya kullanarak kullanmayı denemek isteyebilirsiniz locate. locateönceden var olan bir veritabanını kullandığından çok daha hızlı olacaktır, ancak komut yakın zamanda yüklendiyse çalışmayacaktır.
user628544

Yanıtlar:


37

İşlevi çalıştırmaya set -xhazırsanız, yürütmeyi izlemek ve PS4değişkeni ayarlamak için kullanarak bilgileri alabilirsiniz .

  1. Ekstra hata ayıklama bilgilerini kaydetmek için bash komutunu --debuggerkullanın veya başka bir şekilde kullanın shopt -s extdebug.

  2. PS4Kaynak satırını göstermek için izleme yapılırken yazdırılan 'istemi' ayarlayın .

  3. İzlemeyi aç.

  4. Daha sonra fonksiyonunuzu çalıştırabilirsiniz ve her satır için fonksiyonun adını alacaksınız.

  5. set +xizlemeyi kapatmak için kullanın .

Yani bu dava için koşarsın

bash --debugger
PS4='+ ${BASH_SOURCE[0]} '
set -x ; __git_ps1 ; set +x

"-x Her basit komutu genişlettikten sonra, komut için, case komut, komut seç veya komut için aritmetik seçip PS4'ün genişletilmiş değerini, ardından komutu ve genişletilmiş argümanlarını veya ilişkili sözcük listesini görüntüleyin." Güzel!
l0b0

25

İşlevi çalıştırmak istemiyorsanız, hala hata ayıklamayı ayarlayabilir ve bilgileri alabilirsiniz. Adımlar

  1. fonksiyon tanımlanmadan önce bash --debuggerveya başlar shopt -s extdebug.
  2. declare -F __git_ps1

ve fonksiyonun tanımlandığı yeri rapor eder.

PS4 ile açıklamalı çalıştırma izini görmeye kıyasla bu yöntemin avantajları

  • Çok daha az çıktı
  • Doğrudan soruya cevap verir.

İcra takibinin avantajları:

  • Tüm çağrılan fonksiyonları bir defada görün
  • Çağrılan işlevler arasındaki ilişkileri görün
  • Özyineleme görmek

Her ikisinin de başında olmasını ve farklı Invocation vakalarında kullanılan farklı dosyaları kapsamasını şiddetle tavsiye ederim .shopt -s extdebug~/.bashrc~/.bash_profile


1
İşlev tanımlandıktan sonrashopt -s extdebug çağrıldığında da çalışır . İşlev bildirilirse satır numaralarının kapalı (geçerli bir hata) olabilir . eval
Stéphane Chazelas 15:17

Vpnc için yanlış yönlendirilmiş bir tamamlamanın peşindeydim. Sonra bash --debuggertamamlama işlevini tanımlamak ve rapordan almak için tamamlamayı tetiklemem gerekti declare -F _vpnc.
Harald

9

@ icarus'un mükemmel çözümü , kelimenin tam anlamıyla tanımlandığı ve evalbaşka bir dosyanın içeriğinin bir sonucu olmadıkça (içinde kaynak olan dosyayı evalgöstereceği) işlevler için işe yarar . Diğer adların, kabuk yerleşiklerinin (gibi echo) ve çalıştırılabilir dosyalarının (ikili ya da değil) kaynak dosyasını yazdırmaz ve bu bilgilerin genel olarak mevcut olmadığına inanıyorum. Bazı komutlar kaynak dosyalarını (normal bir uygulama sırasında veya bir sinyale karşılık olarak) yazdırabilir (hatta bu konuda doğru olabilir).

__git_ps1tanımlanır /usr/share/git/git-prompt.shve /usr/share/git/completion/git-prompt.shsistemimin Arch Linux üzerinde, bu yüzden sizin için aynı olabilir.

Özel olarak, kabuğun başlangıcında kaynaklanmış komutları aramak istiyorsanız , Çağrı bölümüne bakın man bash- sırayla diğer dosyaları da kaynaklayan başka dosyaları da kaynaklayabilirler.


Biri başlangıçta elde edilen dosyaların listesini alabilir bashmi?
pfnuesel

@pfnuesel - sana kalmış. Varsayılanlar içeride $HOME/.bashrcve içeridedir $HOME/.profile. Bakınız: her dosyanın ne zaman ve nasıl kaynaklandığı ile ilgili bazı ayrıntıları açıklayan linuxfromscratch.org/blfs/view/svn/postlfs/profile.html .
Joe

2
@Joe gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html çok daha iyi bir referanstır. /etc/profile, $HOME/.bash_profile, $HOME/.bash_login, İçeriği ve $ENVve $BASH_ENVihtiyaç listenize eklenecek.
icarus

@icarus - Teşekkürler. Bu daha iyi bir açıklama.
Joe,

8

Bu mümkün görünmüyor bash, ancak içinde zsh:

$ type __git_ps1
> __git_ps1 is a shell function from /usr/share/git/git-prompt.sh

Soru bash belirtiyor ...
Jeff Schaller

4
@JeffSchaller: Bu cevabı kullanmanın en açık yolu, bash ile aynı dosyaları elde etmek için zsh'yi ayarlamak, sonra tanımı bulmak için kullanmaktır. Bu cevap, zsh'ye geçmeyi önermiyor, sadece açıkça find/ locate/ gibi genel araçlardan daha iyi kabuk sözdizimini anlayan kullanışlı bir araç grep.
Peter Cordes,

O zaman, @PeterCordes, bu cevabın şu anda Soruyu cevaplamak için yapması gereken şeyi yapmadığını iddia ediyorum. Zsh, bash ile aynı dosyaları yerel olarak okuyor mu bilmiyorum.
Jeff Schaller

@JeffSchaller: Bu cevabın iyileştirilmeye ihtiyacı olduğunu kabul etti. zsh neredeyse kesinlikle ~/.whatevervarsayılan olarak bash ile aynı dosyaları okumaz ve yalnızca bu durumda olduğu gibi paylaşılan yerlerde tanımlanmış fonksiyonlar için faydalı cevaplar verecektir ~/.bashrc.
Peter Cordes

-1

Aynı isimde bir fonksiyon bildiriniz ve mümkün olduğu kadar erken okuyunuz, sonra xtrace modunu etkinleştiriniz, şöyle:

__git_ps1(){ :;}
readonly -f __git_ps1
set -x

Bundan sonra giriş yaptığınızda, dosyaların kaynak kodunu içeren izleme bilgilerini görürsünüz. Şu anda var olan salt okunurluk işlevinin bir bildirimi için bir girişim var, bir hata mesajı göreceksiniz. Öncesindeki son kaynak dosya, aradığınız bildirimi içermelidir.

Bunu sistem bash profiline koymanız gerekebilir. Ayrıca suçluyu bulduktan sonra değişiklikleri geri almayı da unutmayın.


-3

Bunu denedin mi?

grep -rnw '/path/to/somewhere/' -e "pattern" 

veya burada bulunan diğer komutlardan herhangi biri:

Linux'ta belirli bir metin içeren tüm dosyaları nasıl bulurum? | Yığın Taşması

Görünüşe göre sana daha fazla açıklama yapmam gerekiyor. Sorunuz "" Dolayısıyla aşağıdaki komutu çalıştırırsanız, bash işlevinin tanımlandığı tüm dosyaları döndürmelidir.

grep -rnw 'Path2Search' -e "#!/bin/bash"

BASH Programlama - İşlevler | Linux Belgelendirme Projesi


1
Link sadece cevaplar kesinlikle teşvik edilmez. Lütfen biraz açıklama ekleyin.
heemayl
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.