Yanıtlar:
Hata ayıklamayı aç. Gönderen Bash kılavuzda :
extdebug
Kabuk çağırmada veya bir kabuk başlangıç dosyasında ayarlanmışsa, kabuk başlamadan önce,
--debuggerseçeneğe benzer hata ayıklayıcı profilini yürütmek için düzenleme yapın . Çağrının ardından ayarlanırsa, hata ayıklayıcıların kullanması amaçlanan davranış etkindir:
-FSeçeneğideclareyerleşiğini (bkz Bash çıkmasını sağlamakta ) bir argüman olarak verilen her işlev adına karşılık gelen kaynak dosya adı ve satır sayısını gösterir.
Örnek:
$ bash --debugger
$ declare -Ff quote
quote 143 /usr/share/bash-completion/bash_completion
Ve gerçekten:
$ nl -ba /usr/share/bash-completion/bash_completion | sed -n 143,150p
143 quote()
144 {
145 local quoted=${1//\'/\'\\\'\'}
146 printf "'%s'" "$quoted"
147 }
148
149 # @see _quote_readline_by_ref()
150 quote_readline()
shopt -s extdebug; declare -Ff quote; shopt -u extdebug.
find_function()( shopt -s extdebug; declare -F "$@"; ). Fonksiyon gövdesindeki parens ile, bir alt kabukta yürütülür ve dükkandaki değişiklik arayanı etkilemez. Ve bu -fgerekli görünmüyor.
Bu aslında ilk başta göründüğünden daha karmaşık. Hangi dosyalar kabuğunuz tarafından okunur , şu anda ne tür bir kabuk çalıştırdığınıza bağlıdır. Etkileşimli olup olmadığına bakılmaksızın, bir giriş mi yoksa giriş olmayan bir kabuk mu ve yukarıdakilerin bir kombinasyonu. Farklı mermiler tarafından okunabilen tüm varsayılan dosyaları aramak için şunları yapabilirsiniz ( $functionNamearadığınız işlevin asıl adını değiştirin ):
grep "$functionName" ~/.bashrc ~/.profile ~/.bash_profile ~/.bash.login \
~/.bash_aliases /etc/bash.bashrc /etc/profile \
/etc/profile.d/* /etc/environment 2> /dev/null
Bu işe yaramazsa, varsayılan olmayan bir dosyayı .ya da diğer adını kullanarak çağırıyor olabilirsiniz source. Bu tür vakaları bulmak için koşun:
grep -P '(^|\s)(\.|source)\s+' ~/.bashrc ~/.profile ~/.bash_profile \
~/.bash.login ~/.bash_aliases /etc/bash.bashrc \
/etc/profile /etc/profile.d/* /etc/environment 2> /dev/null
Bu muhtemelen biraz açıklama gerektiriyor. -PBize biraz daha süslü regex sözdizimi kullanmasına izin Perl Uyumlu Normal İfadeler (PCRE) sağlar. özellikle:
(^|\s): bir satırın başlangıcıyla ( ^) veya boşlukla ( \s) eşleşir .(\.|source)\s+: değişmez .karakter ( \.) veya sözcüğü eşleştirin source, ancak yalnızca bir veya daha fazla boşluk karakteri izlerse eşleştirin .İşte benim sistemimde bana ne veriyor:
$ grep -P '(^|\s)(\.|source)\s+' ~/.bashrc ~/.profile ~/.bash_profile \
> ~/.bash.login ~/.bash_aliases /etc/bash.bashrc \
> /etc/profile /etc/profile.d/* /etc/environment 2> /dev/null
/home/terdon/.bashrc: . /etc/bashrc
/home/terdon/.bashrc: . /etc/bash_completion
/home/terdon/.bashrc:. $HOME/scripts/git-prompt.sh
/home/terdon/.bashrc:# echo -n "$n : "; grep "^CA" $n |perl -e 'my ($a,$c)=0; while(<>){$c++;next if /cellular_component_unknown/; next if /biological_process/; $a++} print "$a Classes of $c annotated (" . $a*100/$c . ")\n"'
/etc/bash.bashrc:[ -r /usr/share/bash-completion/bash_completion ] && . /usr/share/bash-completion/bash_completion
/etc/profile: test -r "$profile" && . "$profile"
/etc/profile: . /etc/bash.bashrc
/etc/profile.d/locale.sh: . "$XDG_CONFIG_HOME/locale.conf"
/etc/profile.d/locale.sh: . "$HOME/.config/locale.conf"
/etc/profile.d/locale.sh: . /etc/locale.conf
/etc/profile.d/Z97-byobu.sh: . /usr/bin/byobu-launch
/etc/profile.d/Z97-byobu.sh: . /usr/bin/byobu-launch
/etc/profile.d/Z97-byobu.sh: . /usr/bin/byobu-launch
/etc/profile.d/Z97-byobu.sh: . /usr/bin/byobu-launch
/etc/profile.d/Z97-byobu.sh: . /usr/bin/byobu-launch
Gördüğünüz gibi, bu, eşleşen çizginin tamamını basacaktır. Gerçekten ilgilendiğimiz şey, onları çağıran satırı değil, adı verilen dosya adlarının listesidir. Bunları daha karmaşık, regex ile alabilirsiniz:
grep -hPo '(^|\s)(\.|source)\s+\K\S+' ~/.bashrc ~/.profile ~/.bash_profile \
~/.bash.login ~/.bash_aliases \
/etc/bash.bashrc /etc/profile \
/etc/profile.d/* /etc/environment 2> /dev/null
-hBayrak bir eşleşme bulunmuştur dosya adları, basılmasını bastırır grepbirden fazla dosya üzerinden arama için söylendi varsayılan olarak yapar. -oVasıta "sadece hattının eşleşen bölümünü yazdırmak". Regex'e eklenen fazladan şeyler:
\K: bu noktaya uyan her şeyi görmezden gelin. Bu, eşinizi bulmak için karmaşık bir regex kullanmanıza izin veren, ancak grep'in -obayrağını kullanırken eşleşen kısmı içermeyen PCRE numarasıdır .Sistemimde yukarıdaki komut dönecektir:
$ grep -hPo '(^|\s)(\.|source)\s+\K\S+' ~/.bashrc ~/.profile ~/.bash_profile \
> ~/.bash.login ~/.bash_aliases \
> /etc/bash.bashrc /etc/profile \
> /etc/profile.d/* /etc/environment 2> /dev/null
/etc/bashrc
/etc/bash_completion
$HOME/scripts/git-prompt.sh
$a*100/$c
")\n"'
/usr/share/bash-completion/bash_completion
"$profile"
/etc/bash.bashrc
"$XDG_CONFIG_HOME/locale.conf"
"$HOME/.config/locale.conf"
/etc/locale.conf
/usr/bin/byobu-launch
/usr/bin/byobu-launch
/usr/bin/byobu-launch
/usr/bin/byobu-launch
/usr/bin/byobu-launch
Ben bir kullanımı için gerçekleştiğini Not .edilir ve ardından bir boşluk değil ben başka bir dil değil, bash aradığını bir takma adı var çünkü kaynak için kullanılan ama bu 's. Garip $a*100/$cve ")\n"'yukarıdaki çıktıda veren budur . Ancak bu göz ardı edilebilir.
Son olarak, tüm bunların bir araya getirilmesi ve tüm varsayılan dosyalarda ve varsayılan dosyalarınızın kaynak olduğu tüm dosyalarda bir işlev adı aranması :
grep_function(){
target="$@"
files=( ~/.bashrc ~/.profile ~/.bash_profile ~/.bash.login
~/.bash_aliases /etc/bash.bashrc /etc/profile
/etc/profile.d/* /etc/environment)
while IFS= read -r file; do
files+=( "$file" )
done < <(grep -hPo '(^|\s)(\.|source)\s+\K\S+' "${files[@]}" 2>/dev/null)
for file in "${files[@]}"; do
## The tilde of ~/ can break this
file=$(sed 's|~/|'"$HOME"'/|g' <<<"$file")
if [[ -e $file ]]; then
grep -H "$target" -- "$file"
fi
done
}
Bu satırları kendinize ekleyin ~/.bashrcve sonra çalıştırabilirsiniz ( fooBarÖrnek bir işlev adı olarak kullanıyorum ):
grep_function fooBar
Örneğin, bu çizgiyi benim yerimde varsa ~/.bashrc:
. ~/a
Ve dosya ~/a:
$ cat ~/a
fooBar(){
echo foo
}
Şunu bulmalıyım:
$ grep_function fooBar
/home/terdon/a:fooBar(){
+=
array+="foo"eklemekten başka foo?
Her zamanki dotfile başına kullanıcı bashokur olduğunu ~/.bashrc. Denilen ayrı dosyalarda takma adları ve işlevleri tutmak gibi Ancak, çok iyi örneğin I diğer dosyaları kaynak oluşturabileceği ~/.bash_aliasesve ~/.bash_functionsdaha kolay onları bulmasını sağlar. .bashrcFor sourcekomutlarını aşağıdakilerle arayabilirsiniz :
grep -E '(^\s*|\s)(\.|source)\s' /home/USERNAME/.bashrc
Kullanıcı tarafından oluşturulan dosyalar listesine sahip olduktan sonra, onları ve kullanıcıyı .bashrctek bir greparama ile arayabilirsiniz, örneğin fookurulumumun işlevi için:
grep foo /home/USERNAME/.bash{rc,_aliases,_functions}