নির্দিষ্ট বাশ ফাংশন সংজ্ঞায়িত যেখানে আমি কীভাবে খুঁজে পাব?


28

অনেকগুলি ফাংশন রয়েছে যা ব্যাশ শেলটিতে ব্যবহার করা যেতে পারে। তাদের সংজ্ঞা দ্বারা তালিকাভুক্ত করা যেতে পারে set, তবে কোন ফাইলের মধ্যে নির্দিষ্ট ব্যবহারকারী সংজ্ঞায়িত ফাংশন সংজ্ঞায়িত করা যায় তা কীভাবে খুঁজে পাবেন?


উত্তর:


32

ডিবাগিং চালু করুন। থেকে ব্যাশ ম্যানুয়াল :

extdebug

যদি শেল ডাকে, বা একটি শেল স্টার্টআপ ফাইলে সেট করা থাকে, --debuggerঅপশনটির অনুরূপ শেল শুরুর আগে ডিবাগার প্রোফাইল চালানোর ব্যবস্থা করুন । যদি অনুরোধের পরে সেট করা থাকে তবে ডিবাগারদের ব্যবহারের উদ্দেশ্যে আচরণটি সক্ষম করা হয়েছে:

  • -Fবিকল্প declarebuiltin (দেখুন ব্যাশ Builtins ) প্রতিটি ফাংশন নাম একটি আর্গুমেন্ট হিসাবে সরবরাহকৃত সংশ্লিষ্ট সোর্স ফাইল নাম এবং লাইন সংখ্যা প্রদর্শন করা হয়।

উদাহরণ:

$ bash --debugger
$ declare -Ff quote
quote 143 /usr/share/bash-completion/bash_completion

এবং প্রকৃতপক্ষে:

$ 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
জার্নো

2
@ জার্নো আহ, ভাল, আমার নামের বিপরীতে, আমি zsh ব্যবহার করি। সে কারণেই আমি একটি নতুন শেল শুরু করেছি। : ডি
বেশিটি এমসিবাশফেস

ওরফে ঘোষণার অবস্থানগুলি খুঁজতে কি একই জাতীয় পদ্ধতি রয়েছে ?
ফেডনকাডিফেলি

@ ফেডন নীচে আমার নিষ্প্রভ এবং জটিল পদ্ধতির কাজ করা উচিত।
টেরডন

1
আপনি এই ভালো একটি ফাংশন বানাতে পারে: find_function()( shopt -s extdebug; declare -F "$@"; )। ক্রিয়াকলাপের প্রধান অংশে প্যারেনস সহ এটি একটি সাবশেলে সম্পাদিত হয় এবং শপগুলিতে পরিবর্তন কলারের ক্ষতি করে না। এবং এটি -fপ্রয়োজন বলে মনে হচ্ছে না।
wjandrea

15

এটি প্রথমে প্রদর্শিত হওয়ার চেয়ে এটি আরও জটিল। আপনার শেল দ্বারা কোন ফাইলগুলি পড়ে তা নির্ভর করে আপনি বর্তমানে কোন ধরণের শেল চালাচ্ছেন তার উপর নির্ভর করে । এটি ইন্টারেক্টিভ হোক বা না হোক, এটি লগইন হোক বা লগইনবিহীন শেল এবং উপরের কোনটি সমন্বিত। বিভিন্ন শেল দ্বারা পড়া যায় এমন সমস্ত ডিফল্ট ফাইল অনুসন্ধান করার জন্য আপনি করতে পারেন ( $functionNameযে ফাংশনটির সন্ধান করছেন তার আসল নামটি পরিবর্তন করুন ):

grep "$functionName" ~/.bashrc ~/.profile ~/.bash_profile ~/.bash.login \
                     ~/.bash_aliases /etc/bash.bashrc /etc/profile \
                     /etc/profile.d/* /etc/environment 2> /dev/null

যদি এটি কাজ না করে তবে আপনি একটি অ-ডিফল্ট ফাইল .বা এটির নাম ব্যবহার করে কল করতে পারেন source। এই জাতীয় কেসগুলি সন্ধান করতে, চালান:

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

এটি সম্ভবত কিছু ব্যাখ্যা প্রয়োজন। -Pপার্ল সামঞ্জস্যপূর্ণ রেগুলার এক্সপ্রেশন (PCRE) যা দিন আমাদেরকে কিছু কল্পনাকারী Regex সিনট্যাক্স ব্যবহার সক্ষম করে। বিশেষ করে:

  • (^|\s): একটি লাইন ( ^) বা সাদা স্থান ( \s) এর শুরুতে মেলে ।
  • (\.|source)\s+: আক্ষরিক .অক্ষর ( \.) বা শব্দের সাথে মেলে sourceতবে কেবল সেগুলি এক বা একাধিক সাদা বর্ণের অক্ষর অনুসরণ করে।

এটি আমার সিস্টেমে আমাকে যা দেয় তা এখানে:

$ 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

আপনি দেখতে পাচ্ছেন, তবে এটি সম্পূর্ণ মিলিত লাইনটি মুদ্রণ করবে। আমরা সত্যিই যা আগ্রহী তা হ'ল ফাইলের নামের তালিকা, যে লাইনটি তাদের কল করছে তা নয়। আপনি এইগুলি আরও জটিল, রেজেেক্সগুলি পেতে পারেন:

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পতাকা ফাইলের নাম যেখানে একটি ম্যাচ পাওয়া যায়নি, যার মুদ্রণ শুষে grepযখন একাধিক ফাইল অনুসন্ধান করতে বলা ডিফল্টরূপে আছে। এর -oঅর্থ "কেবলমাত্র লাইনের সাথে মিলে যাওয়া অংশটি মুদ্রণ করুন"। রেজেক্সে যুক্ত অতিরিক্ত জিনিসগুলি হ'ল:

  • \K: এই বিন্দুতে মিলেছে এমন কিছু উপেক্ষা করুন। এটি একটি পিসিআরই ট্রিক যা আপনাকে আপনার ম্যাচ সন্ধানের জন্য একটি জটিল রেইগেক্স ব্যবহার করতে দেয় তবে গ্রেপের -oপতাকা ব্যবহার করার সময় সেই ম্যাচের অংশটি অন্তর্ভুক্ত করে না ।

আমার সিস্টেমে উপরের কমান্ডটি ফিরে আসবে:

$ 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

মনে রাখবেন যে আমার .কোনও স্থান অনুসরণ করার পরে এমন একটি জায়গা রয়েছে যা সোসিংয়ের জন্য ব্যবহৃত হয় না তবে তা কারণ আমার একটি উলাম আছে যা অন্য ভাষায় ডাকছে, বাশ নয়। এটিই কি অদ্ভুত $a*100/$cএবং ")\n"'উপরের আউটপুটটিতে দেয় । তবে তা উপেক্ষা করা যায়।

সবশেষে, কীভাবে সেগুলি সমস্ত একসাথে রাখা যায় এবং সমস্ত ডিফল্ট ফাইলগুলিতে কোনও ফাংশনের নাম অনুসন্ধান করতে এবং আপনার ডিফল্ট ফাইলগুলি সোরসিং করছে এমন সমস্ত ফাইল:

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
}

সেই লাইনগুলিকে আপনার যুক্ত করুন ~/.bashrcএবং তারপরে আপনি চালাতে পারেন (আমি fooBarউদাহরণ ফাংশন নাম হিসাবে ব্যবহার করছি ):

grep_function fooBar

উদাহরণস্বরূপ, যদি আমার এই লাইনটি থাকে ~/.bashrc:

. ~/a

এবং ফাইলটি ~/aহ'ল:

$ cat ~/a
fooBar(){
  echo foo
}

আমার সাথে এটি খুঁজে পাওয়া উচিত:

$ grep_function fooBar
/home/terdon/a:fooBar(){

আপনার সমাধানটি একটি দুর্দান্ত শিক্ষামূলক স্ক্রিপ্টিং উদাহরণ, তবে আমি বাশিতি এমসিবাশফেসের সমাধানটি আরও সহজ।
জার্নো

@ জার্নো এবং এটি অনেক অনেক সহজ! :)
টেরডন

অ্যারে সমর্থন+=
ডি বেন নোবল

@ D.BenKnoble তারা কি করে? আপনি অ্যারের প্রথম উপাদানটিতে array+="foo"স্ট্রিং সংযোজন ছাড়া অন্যটি বোঝাতে চান foo?
টেরডন

1
@ ডি.বেনকনবল ধন্যবাদ! আমি জানতাম না বাশ অ্যারে সেই স্বরলিপিটি সমর্থন করেছিল!
টারডন

2

স্বাভাবিক ব্যবহারকারী অনুসারে dotfile bashসার্চ ~/.bashrc। তবে এটি অন্যান্য ফাইলগুলিকে খুব ভাল উত্স করতে পারে, উদাহরণস্বরূপ আমি আলাদা আলাদা আলাদা ফাইলগুলিতে ডাকনাম এবং ফাংশন রাখতে চাই ~/.bash_aliasesএবং ~/.bash_functionsযা তাদের সন্ধান করা আরও সহজ করে তোলে। আপনি অনুসন্ধান করতে পারেন .bashrcজন্য sourceসঙ্গে কমান্ড:

grep -E '(^\s*|\s)(\.|source)\s' /home/USERNAME/.bashrc

একবার আপনার ব্যবহারকারীর দ্বারা নির্মিত ফাইলগুলির তালিকা পাওয়া গেলে আপনি সেগুলি এবং .bashrcএকক grepকল দিয়ে ব্যবহারকারীর অনুসন্ধান করতে পারেন , যেমন fooআমার সেটআপটির জন্য ফাংশনটির জন্য:

grep foo /home/USERNAME/.bash{rc,_aliases,_functions}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.