これらの制約を満たす方法はありません

これらの制約を満たす方法はありません

zshは良いものを提供しますフック機能chpwdユーザーがディレクトリを変更した後に実行される機能が含まれています。

# zsh only
function greet() { echo 'hi'; }
chpwd_functions+=("greet")
cd .. # hi
pushd # hi
popd  # hi

私はこれをbashでエミュレートしようとしています。

制限要因:

  • 対話型シェルと非対話型シェルの両方で機能する必要があります。これは、次のことに頼ることができないことを意味すると思います。$PROMPT_COMMAND
  • cdディレクトリを変更するコマンド(たとえば、pushdおよびpopd)と連携したいので、上書きすることはできません。
  • 実行する必要があります後ろにユーザーのコマンドを実行するので、trap "my_function" DEBUG「最初に問題のあるコマンドを実行してからこの操作を実行してください...」と言えないと機能しません。$BASH_COMMAND自動実行を避けることができることがわかりました。$BASH_COMMAND もし extdebug有効そしてトラップ関数は1を返しますが、強制的に実行したくないので、成功した(しかし修正された)コマンドをextdebug返すのは間違っているようです。1

最後の部分である「ユーザーコマンドによる実行」は、現在私を混乱させます。もし私ができる各コマンドの後に関数を実行すると、最後に確認した後にディレクトリが変更されたことを確認できます。たとえば、

function check_pwd() {
  # true in a new shell (empty var) or after cd
  if [ "$LAST_CHECKED_DIR" != "$PWD" ]; then
    my_function
  fi
  LAST_CHECKED_DIR=$PWD
}

私は正しい道を行っていますか、それとも良い道ですか?ユーザーがディレクトリを変更した後にbashでコマンドを実行する方法は?

ベストアンサー1

これらの制約を満たす方法はありません

私の制限を考えると、bashはこの問題を解決する方法がないようです。一般的に考えられる解決策は次のとおりです。

  • cdpushdおよびをオーバーライドして、ディレクトリpopdを変更するすべてのコマンドにフック機能を最初に実行させます。ただし、これは問題を引き起こす可能性があります。 1)オーバーライドは元のコマンドと同じくらい慎重に実行し、同じ終了コードを返す必要があります。2)複数のツールがこのアプローチを使用している場合、それはうまく機能しません。
  • フック機能を最初に実行するには、環境が変更されたときに実行される可能性のあるすべてのコマンドをオーバーライドします。このような命令がたくさんあるので難しいです。
  • trap 'my_function' DEBUGこれにより、すべてのコマンドがフック機能を実行します。これは、1) すべての命令の前に実行され、2) 実行されるため、次善策です。今後 cd、代わりに3)デバッグ機能は1つしかないため、他のツールでこのアプローチを使用すると一緒にうまく機能しません。
  • $PROMPT_COMMANDまず、実行するHook関数をオーバーライドします。これは非対話型シェルでは機能しないため、他のツールでプロンプトコマンドを定義した場合はうまく機能しないため、これは最適です。

簡単に言えば、bashがchpwd_functionszshellフックのようなものを提供することは唯一の良い解決策であるようですが、それを正しくエミュレートすることは不可能です。

おすすめ記事