BASHの$ PROMPT_COMMANDに相当するZSHは何ですか?


24

BASHは、$PROMPT_COMMAND第1レベルのインタラクティブプロンプトの前に実行されるコマンドを定義する環境変数をサポートしています。私はそれと同等のZSHを探しています。

ドキュメントには、それprecmdを実現するために定義できる関数があると書かれています。ただし、環境変数から定義する方法はわかりません。

ZSHにその関数の定義を含むファイルを読み取らせる環境変数を渡すことを検討しましたが、ZSH はそのようなことをサポートしていないようです。グローバルファイルとユーザーごとのファイルのみを読み取ります。それらを置き換えることはできますが、ファイルを変更せずに追加することはできません。

それでは$PROMPT_COMMAND、BASHで使用するように、環境変数を介してZSHで事前プロンプトフックを定義するにはどうすればよいですか?


真実は、対話型コマンド実行後のフックが必要ですが、どちらのシェルも提供しないため、事前プロンプトフックに頼らなければなりません-可能な限り近いようです。
Shnatsel

1
フム、私は疑問に思って、何の違いポスト対話方式コマンド実行事前プロンプトです。概念的な違いは別として、実際にどこで違いを観察しますか。(レッツ・オミットコマンドexitexec、OK ;)
MPY

バックグラウンドジョブはプロンプトシーケンスから独立しているため、@ mpyはバックグラウンドジョブの実行時に違いがあります。
Shnatsel

1
わかりました、私はそのポイントを得ました。では、そのようなものについてはどうでしょうか:start() { eval "$@"; echo post-command-code }そして、zle-bindingを使用して、コマンドラインをstart先頭に追加して実行しますか?
mpy

1
DEBUGトラップは素敵な見つけることですが、あなたはまだそれを定義するためにどのように問題を抱えています。回答をもう一度拡張しましたが、DEBUGトラップソリューションに関する独自の回答を作成するのはあなたにお任せします。:)
mpy 14

回答:


24

$PROMPT_COMMAND私の頭に浮かぶbashをエミュレートする最も簡単なアプローチはprecmd、既に理解したように、フックを使用することです。定義します

precmd() { eval "$PROMPT_COMMAND" }

そして、あなたはそのようなことをすることができます:

$ PROMPT_COMMAND='echo Hello, it is now $(date)'
Hello, it is now Mon, Mar 31, 2014 7:08:00 PM
$ whoami      
user
Hello, it is now Mon, Mar 31, 2014 7:08:21 PM     
$

その例の単一引用符に注意してください。$(date)さも$PROMPT_COMMANDないと、プロンプトの前に呼び出されたときではなく、定義時に既に展開されます。


既存の定義を保持したい(変更したくない)場合は、そのアプローチを使用できます。

$ prmptcmd() { eval "$PROMPT_COMMAND" }
$ precmd_functions=(prmptcmd)

それによりprmptcmd、既存のprecmd()関数の後に関数が実行されます。


最後に、プログラムパッケージでの使用に適した方法を次に示します。この方法では、ユーザーファイルやシステムファイルを変更したり、コマンドをインタラクティブに入力したりすることはできません。

bashセッションを生成する例は次のとおりです。

PROMPT_COMMAND="echo foo" bash

zshをスポーンするには、使用できます

ZDOTDIR=/program/dir zsh

これが原因/program/dir/.zshrcとなります。このファイルでは、precmd()上記で説明したようにフックを定義できます。あなたは、ユーザーの設定したい場合以外には含まれsource $HOME/.zshrcすぎて、プログラムの.zshrcになど。プログラムディレクトリ以外のファイルは変更されないため、このセットアップは維持可能です。


最後に、newuserを歓迎する方法の概念実証を示します。/program/dir/.zshenvrc構成ファイルで次のコードを使用します。

echo define precmd, traps, etc.

autoload -Uz zsh-newuser-install

if [[ ! -e "$HOME/.zshrc" ]]; then
  zsh-newuser-install -f
  mv $ZDOTDIR/.zshrc $HOME/.zshrc
else
  builtin source $HOME/.zshrc
fi

そんなに私は考えた。問題は-環境変数を介してprecmdフックを定義するにはどうすればよいですか?ファイルを変更せずにフックまたはコードを追加するメカニズムはありますか?または、少なくともグローバルおよびユーザーグローバルの「.zprofile」および同様のファイルに書き込むことなく、どうすればよいですか?たとえば、既存のものを置き換えない独自の.zprofileを追加できますか?
Shnatsel

1
また、ここでprecmdフックを使用すると、既存のprecmdフックが置き換えられます。zsh docsには、共存する関数の配列を作成できると書かれていますが、その方法はわかりません。
Shnatsel

1
(1)環境変数を介してprecmdフックを定義するにはどうすればよいですか?私が提示した例は、bashメカニズムのような私見で動作します。(2)コマンドラインからフックを追加できますが、それは永続的ではありません。あなたの変更の問題は何.zshrcですか?(3)例:foo() { echo foo }; bar() { echo bar }; precmd_functions=(foo bar)この実行foo()bar() 加えしますprecmd()
mpy 14年

2
わかりました、それは多くを明確にします-bashの最小の例はそうでしょうPROMPT_COMMAND="echo foo" bash?これは、zsh:を生成する可能性がありますZDOTDIR=/program/dir zsh。次に/program/dir/.zshrc、起動時にprecmd()フックを定義できるソースになります。ユーザーの追加をsource $HOME/.zshrcプログラムのzshrcに含めるなどしたい場合。プログラムdir以外のファイルは変更されないため、これは維持しやすいはずです。
mpy 14

1
@Shnatsel:答えを広げました。質問を編集して、コメントの追加情報を含めることもできます。
mpy 14

5

@mypyが述べているように、Zsh precmdはBashと同様に機能しPROMPT_COMMANDます。

BashまたはZshで機能し、使用しない例はeval次のとおりです。

## ~/myprompt.sh

# 'ZSH_VERSION' only defined in Zsh
# 'precmd' is a special function name known to Zsh

[ ${ZSH_VERSION} ] && precmd() { myprompt; }

# 'BASH_VERSION' only defined in Bash
# 'PROMPT_COMMAND' is a special environment variable name known to Bash

[ ${BASH_VERSION} ] && PROMPT_COMMAND=myprompt

# function called every time shell is about to draw prompt
myprompt() {
  if [ ${ZSH_VERSION} ]; then
    # Zsh prompt expansion syntax
    PS1='%{%F{red}%}%n%{%f%}@%{%F{red}%}%m %{%F{cyan}%}%~ %{%F{white}%}%# %{%f%}'
  elif [ ${BASH_VERSION} ]; then
    # Bash prompt expansion syntax
    PS1='\[\e[31m\]\u\[\e[0m\]@\[\e[31m\]\h \[\e[36m\]\w \[\e[37m\]\$ \[\e[0m\]'
  fi
}

シェルの初期化スクリプトから実行します。

## ~/.bashrc
. ~/myprompt.sh

そして:

## ~/.zshrc
. ~/myprompt.sh

ここでのプロンプトは単なる例です。間違いなくはるかにトリッキーなことができます。

プロンプト機能の設定の詳細については、http//zsh.sourceforge.net/Doc/Release/Functions.html#index-precmdおよびhttp://www.gnu.org/software/bash/manual/bashref.htmlを参照してください。 #印刷-プロンプト

プロンプト展開の詳細については、http://zsh.sourceforge.net/Doc/Release/Prompt-Expansion.htmlおよびhttp://www.gnu.org/software/bash/manual/bashref.html#Printing-aを参照してください。 -プロンプト

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.