bash / zshから関数とすべての対応するシェル関連の依存関係を抽出する方法は?

bash / zshから関数とすべての対応するシェル関連の依存関係を抽出する方法は?

私は便利な小さな機能をたくさん書いて、時には友人や世界と共有するのが好きです。問題は、私の関数にヘルパー関数とエイリアスをたくさん使用していますが、関数コードを1行ずつ読み、すべての依存関係を見つける動機がないことです。このプロセスは自動化できると確信しています。まず、エクスポートする関数のコード(which funcコードを取得するために使用されます)にタグを付けてから、そのタグのエイリアスをエクスポートし、各タグに対してこのプロセスを繰り返し繰り返す必要があります(aを実行し、which tokenそれが存在し、シェルに関連付けられている確認してください(したがって、バイナリに対して何もしないか、オプションですべてのバイナリをbinary.txtに追加してから繰り返します)。

このユースケースの既存のツールはありますか?

そうでない場合は、コードをどのように表示しますか?

更新:私が提案したアプローチが無関係なアイテムをエクスポートし、すべての依存関係をエクスポートするという保証はありませんが、私のコードでは機能することを知っています。

更新:私の関数は単純な傾向があるので、エクスポートツールがサンプル引数を使用して関数を実行し、この特定の実行に必要なすべての依存関係をエクスポートした場合でも問題ありません。

ベストアンサー1

シェルがコードを解釈する方法は、おおよその経験的方法によってのみおおよそ推定できます。たとえば、極端なケースでは、次のことがわかりません。

foo() { "${0+b}$(echo AR | tr '[:upper:]' '[:lower:]')$1"; }
bar() { for i in 1 2; do foo "$i" "$i"; }

bar機能頼るonfooであり、これを実行せずに動作します(bar1そしてbar2すべてのコードパスを介して強制的に実行する必要があります)。

zshz実際には、シェルトークン演算子であるパラメータ拡張フラグ(Q最初のレベル参照を削除するためにも使用されます)があります。しかし、それはあなたが望むものではありません。

たとえば、 を返し、f() { foo "bar baz" "bar $(bar)"; }関数呼び出しを見逃します。${(z)functions[f]}foo"bar baz""bar $(bar)"bar

1つのアプローチは、一般的な関数名のように見える単語を抽出することです(zsh関数名は何でも含めることができますが、人々は[[:alnum:]:._-]文字以外はほとんど使用しません)。次に、関数名のリストと比較して確認します。

all_functions=(${(k)functions})
list-functions() (
  typeset -aU processed unprocessed=("$@") new list
  while (($#unprocessed)) {
    for f ($unprocessed) {
      autoload +X $f 2> /dev/null
      list=(${(s.:.)functions[$f]//[^[:alnum:]:._-]/:})
      new+=(${all_functions:*list})
      processed+=($f)
    }
    unprocessed=(${new:|processed})
  }
  print -rol -- $processed
)

_path_commands私が得た完成システムの機能をテストする方法は次のとおりです。

_all_labels
_alternative
_arguments
c
_cache_invalid
_call_program
_call_whatis
_command_names
_complete
_completers
_dates
_delimiters
_describe
_description
_dispatch
_files
_globflags
_globqual_delims
_globquals
_groups
_have_glob_qual
_history_modifiers
_ignored
_jobs
_list_files
_main_complete
_message
_next_label
_next_tags
_nm
_normal
_object_files
_parameters
_path_commands
_path_commands_caching_policy
_path_files
_pick_variant
_requested
_retrieve_cache
_services
_set_command
_setup
_store_cache
_suffix_alias_files
_tags
u
_users
_wanted

functions $(list-functions _path_commands)これらすべての関数の定義をダンプするには実行してください)。

そこに少なくとも2つの偽の肯定を見つけることができます:cu、 my の2つの関数~/.zshrc。変数名やパラメータ拡張フラグ、または一部のコマンドパラメータの単語として使用することもできますが、cこれuについて何もできることはありません。

私はエイリアスについてあまり心配しません。関数の実行時にエイリアスは拡張されません。関数が定義またはロードされると拡張されますが、後続の出力には拡張functions形式が表示されます。

おすすめ記事