139

この素晴らしいスレッドを見ていると、いくつかの例が使用されていることに気付きました

PS1="Blah Blah Blah"

そしていくつかの使用

PROMPT_COMMAND="Blah Blah Blah"

Bash シェルでプロンプトを設定するときに (両方を使用するものもあります)。2つの違いは何ですか?スタック オーバーフロー検索や、Google 検索を少し広げても結果が得られないため、答えを探すための適切な場所へのリンクを提供していただければ幸いです。

4

6 に答える 6

76

PROMPT_COMMANDには通常のBashステートメントを含めることができますが、PS1変数には、変数にホスト名の「\h」などの特殊文字を含めることもできます。

たとえば、これがPROMPT_COMMANDとPS1の両方を使用するBashプロンプトです。PROMPT_COMMANDのBashコードは、どのGitブランチにいるかを判断し、最後に実行されたプロセスの終了ステータス、ホスト名、およびpwdのベース名とともにプロンプ​​トに表示します。

変数RETは、最後に実行されたプログラムの戻り値を格納します。これは、ターミナルで最後に実行したプログラムのエラーとエラーコードがあったかどうかを確認するのに便利です。PROMPT_COMMAND式全体を囲む外側の'に注意してください。PS1が含まれているため、PROMPT_COMMAND変数が評価されるたびにこの変数が再評価されます。

PROMPT_COMMAND='RET=$?;\
  BRANCH="";\
  ERRMSG="";\
  if [[ $RET != 0 ]]; then\
    ERRMSG=" $RET";\
  fi;\
  if git branch &>/dev/null; then\
    BRANCH=$(git branch 2>/dev/null | grep \* |  cut -d " " -f 2);\
  fi;
PS1="$GREEN\u@\h $BLUE\W $CYAN$BRANCH$RED$ERRMSG \$ $LIGHT_GRAY";'

Git以外のディレクトリでの出力例は次のようになります。

sashan@dhcp-au-122 Documents  $ false
sashan@dhcp-au-122 Documents  1 $

そして、Gitディレクトリにブランチ名が表示されます。

sashan@dhcp-au-122 rework mybranch $

アップデート

コメントとボブの答えを読んだ後、彼が説明するようにそれを書く方が良いと思います。PS1変数がBashによって実行時に評価される非常に複雑な文字列であるPROMPT_COMMAND内に設定されている、私が最初に書いたものよりも保守しやすくなっています。

動作しますが、必要以上に複雑です。公平を期すために、私は約10年前に自分でそのPROMPT_COMMANDを作成しましたが、それは機能し、あまり考えていませんでした。

私が自分のことをどのように修正したかについて興味がある人のために、私は基本的にPROMPT_COMMANDのコードを別のファイルに入れ(ボブが説明したように)、PS1になる予定の文字列をエコーし​​ます。

GREEN="\[\033[0;32m\]"
CYAN="\[\033[0;36m\]"
RED="\[\033[0;31m\]"
PURPLE="\[\033[0;35m\]"
BROWN="\[\033[0;33m\]"
LIGHT_GRAY="\[\033[0;37m\]"
LIGHT_BLUE="\[\033[1;34m\]"
LIGHT_GREEN="\[\033[1;32m\]"
LIGHT_CYAN="\[\033[1;36m\]"
LIGHT_RED="\[\033[1;31m\]"
LIGHT_PURPLE="\[\033[1;35m\]"
YELLOW="\[\033[1;33m\]"
WHITE="\[\033[1;37m\]"
RESTORE="\[\033[0m\]" #0m restores to the terminal's default colour

if [ -z $SCHROOT_CHROOT_NAME ]; then
    SCHROOT_CHROOT_NAME=" "
fi
BRANCH=""
ERRMSG=""
RET=$1
if [[ $RET != 0 ]]; then
    ERRMSG=" $RET"
fi
if which git &>/dev/null; then
    BRANCH=$(git branch 2>/dev/null | grep \* |  cut -d " " -f 2)
else
    BRANCH="(git not installed)"
fi
echo "${GREEN}\u@\h${SCHROOT_CHROOT_NAME}${BLUE}\w \
${CYAN}${BRANCH}${RED}${ERRMSG} \$ $RESTORE"

そして私の.bashrcファイルでは:

function prompt_command {
    RET=$?
    export PS1=$(~/.bash_prompt_command $RET)
}
PROMPT_DIRTRIM=3
export PROMPT_COMMAND=prompt_command
于 2010-06-17T01:45:47.807 に答える
70

GNU Bash ドキュメント ページ ( Bash リファレンス マニュアル) から:

PROMPT_COMMAND
    If set, the value is interpreted as a command to execute before
    the printing of each primary prompt ($PS1).

私はそれを使用したことはありませんが、 shしか持っていなかったときにこれを使用できたはずです。

于 2010-06-17T01:38:00.433 に答える
50

違いは、PS1使用される実際のプロンプト文字列でありPROMPT_COMMAND、プロンプトの直前に実行されるコマンドです。プロンプトを構築する最も簡単で柔軟な方法が必要な場合は、これを試してください。

これを.bashrcファイルに入れます:

function prompt_command {
  export PS1=$(~/bin/bash_prompt)
}
export PROMPT_COMMAND=prompt_command

次に、スクリプト (Bash、Perl、またはRubyから選択) を作成し、ファイル~/bin/bash_promptに配置します。

スクリプトは、任意の情報を使用してプロンプトを作成できます。PS1これは、変数のためだけに開発されたややバロックな置換言語を学ぶ必要がないため、IMO の方がはるかに簡単です。

~/bin/bash_promptPROMPT_COMMANDに直接設定し、空の文字列に設定するだけで同じことができると思うかもしれません。PS1

これは最初は機能しているように見えますが、すぐに readline コードPS1が実際のプロンプトに設定されることを期待していることに気付き、履歴を逆方向にスクロールすると、結果として混乱が生じます。

この回避策によりPS1、常に最新のプロンプトが反映されます (シェルの呼び出しインスタンスによって使用される実際のPS1変数が関数によって設定されるため)。これにより、readline とコマンド履歴が正常に機能します。

于 2012-06-19T18:57:49.037 に答える
12

からman bash:

PROMPT_COMMAND

設定されている場合、値は各プライマリ プロンプトを発行する前にコマンドとして実行されます。

PS1

このパラメーターの値は拡張され (以下の PROMPTING を参照)、プライマリ プロンプト文字列として使用されます。デフォルト値は「\s-\v\$」です。

単にプロンプ​​ト文字列を設定したい場合は、単独で使用するPS1だけで十分です:

PS1='user \u on host \h$ '

プロンプトを出力する直前に何か他のことをしたい場合は、 を使用してくださいPROMPT_COMMAND。たとえば、キャッシュされた書き込みをディスクに同期する場合は、次のように記述できます。

PROMPT_COMMAND='sync'
于 2014-07-20T04:07:10.903 に答える
1

違いは、

  • から不完全な行を出力するPROMPT_COMMANDと、Bashプロンプトが台無しになります
  • PS1身代わり\Hと友達
  • PROMPT_COMMANDその内容を実行し、PS1その内容をプロンプトとして使用します。

PS1各プロンプトで変数展開とコマンド置換を行います。PROMPT_COMMAND値を割り当てPS1たり、任意のコードを実行したりするために使用する必要はありません。export PS1='$(uuidgen) $RANDOM'file で一度簡単に実行できます.bash_profile。一重引用符のみを使用してください。

于 2018-09-10T17:08:17.223 に答える
1

ええ、これを本当に突き止めようとするために:

  • PROMPT_COMMANDは便利なBashPS1の便利な変数/関数ですが、厳密に言えば、単独でもできないことはありませんよね?

つまり、プロンプトの外でスコープを持つ別の変数を設定 したい場合: シェルによっては、その変数を最初に外で宣言する必要があるか、(最悪の場合) プロンプトの前に FIFO で待機している何かに夢中になる必要があるかもしれません。呼び出し(およびの最後に再び武装); 特に派手な正規表現を使用している場合は、これが問題を引き起こす可能性があります。しかし、それ以外の場合:内部でコマンド置換を使用することで、何かを達成できます(そして、場合によっては、明示的なサブシェル)?$PS1$PS1$PS1\u \hPROMPT_COMMAND$PS1

右?

于 2019-05-07T07:57:28.963 に答える