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,
--debugger
seç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:
-F
Seçeneğideclare
yerleş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 -f
gerekli 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 ( $functionName
aradığı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. -P
Bize 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
-h
Bayrak bir eşleşme bulunmuştur dosya adları, basılmasını bastırır grep
birden fazla dosya üzerinden arama için söylendi varsayılan olarak yapar. -o
Vası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 -o
bayrağı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/$c
ve ")\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 ~/.bashrc
ve 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ı bash
okur 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_aliases
ve ~/.bash_functions
daha kolay onları bulmasını sağlar. .bashrc
For source
komutları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ı .bashrc
tek bir grep
arama ile arayabilirsiniz, örneğin foo
kurulumumun işlevi için:
grep foo /home/USERNAME/.bash{rc,_aliases,_functions}