web-dev-qa-db-ja.com

PS1とPrompt_COMMANDの違いは何ですか

この素晴らしいスレッド を見ていると、いくつかの例が

PS1="Blah Blah Blah"

そして、いくつかの使用

Prompt_COMMAND="Blah Blah Blah"

(および一部は両方を使用します)bashシェルでプロンプトを設定する場合。 2つの違いは何ですか? SO検索と、より広範なGoogle検索でも結果が得られないので、答えを探すための適切な場所へのリンクも歓迎します。

98
Jed Daniels

GNU Bash docページから: http://www.gnu.org/software/bash/manual/bashref.html

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

使用したことはありませんが、shしかなかったときにこれを使用できました。

55
Scott Thomson

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変数がPrompt_COMMAND内に設定され、それ自体が実行時にbashによって評価される非常に複雑な文字列である、上記で最初に書いたものよりも保守性が高いです。動作しますが、必要以上に複雑です。公平を期して、私は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
65
sashang

違いは、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の方がはるかに簡単です。

Prompt_COMMANDを〜/ bin/bash_Promptに直接設定し、PS1を空の文字列に設定するだけで、同じことができると考えるかもしれません。これは最初は動作しているように見えますが、readlineコードはPS1が実際のプロンプトに設定されることを期待しており、履歴内のバックワードをスクロールすると、結果として混乱することがわかります。この回避策により、PS1は常に最新のプロンプトを反映し(関数はシェルの呼び出しインスタンスによって使用される実際のPS1を設定するため)、これによりreadlineとコマンド履歴が正常に機能します。

44
Bob

man bash から:

Prompt_COMMAND

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

PS1

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

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

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

プロンプトを印刷する直前に何か他のことをしたい場合は、Prompt_COMMANDを使用します。たとえば、キャッシュされた書き込みをディスクに同期する場合、次のように書き込むことができます。

Prompt_COMMAND='sync'
9
Cyker

ええ、それで本当にこれを釘付けにしようとする:

  • Prompt_COMMANDは便利ですbash便利な変数/関数ですが、厳密に言うと、PS1だけではできないことはありませんか?

つまり、プロンプト外のスコープを持つsetanother変数:シェルに応じて、その変数はおそらく最初に$PS1の外で宣言する必要があります(最悪の場合)$PS1を呼び出す前にFIFO $PS1)の最後; \u\hは、特に派手な正規表現を使用している場合に問題を引き起こす可能性がありますが、それ以外の場合:Prompt_COMMAND$PS1内でコマンド置換を使用します(場合によっては、場合によっては明示的なサブシェル)。

右?

0
Geoff Nixon

違いは

  • _Prompt_COMMAND_から不完全な行を出力すると、bashプロンプトが台無しになります
  • _PS1_は_\H_と友達を置き換えます
  • _Prompt_COMMAND_はその内容を実行し、_PS1_はその内容をプロンプトとして使用します。

_PS1_は各プロンプトで変数の展開とコマンドの置換を行います。_Prompt_COMMAND_を使用して値を_PS1_に割り当てたり、任意のコードを実行したりする必要はありません。 _.bash_profile_でexport PS1='$(uuidgen) $RANDOM'を1回簡単に実行でき、単一引用符を使用するだけです

0
pal