バッシュマニュアル

バッシュマニュアル

.bash_historyPROMPT_COMMAND次の設定を使用して、すべてのターミナルタブとウィンドウでコマンド履歴を有効にしたいと思います.profile

export PROMPT_COMMAND="history -a; history -c; history -r;$PROMPT_COMMAND"

ただし、この環境変数が設定されていることを確認すると、次の結果が表示されます。

echo $PROMPT_COMMAND
printf "\033]0;%s@%s:%s\007" "${USER}" "${HOSTNAME%%.*}" "${PWD/#$HOME/\~}"

PROMPT_COMMANDこのようにエクスポートすると既存のリストが上書きされますか、またはエクスポートする前に値の前にプレフィックスを付ける必要が$PROMPT_COMMANDありますか?PROMPT_COMMAND:

ベストアンサー1

Google検索でのトップ結果の1つであるこの"PROMPT_COMMAND seperator"回答は、これまでに提供されたものよりも多くの努力を払う価値があると思います。

メモ:この投稿を準備しながら、Bashバージョン3.2、4.4、5.0、および5.1をテストしました。ドッカー)同じバージョンのソースコードを確認しました。gnu.org)

始めましょう...


バッシュマニュアル

バッシュ<= v5.0

PROMPT_COMMAND変数の値は以前にチェックされます。
Bashは各キープロンプトを印刷します。 PROMPT_COMMANDが設定されている
NULL以外の値がある場合は、NULL以外のように値を実行します。
すでにコマンドラインに入力されています。

どういう意味ですか?

言い換えれば、bashは次のようにほぼ同じことを行います。

eval "${PROMPT_COMMAND:-}"

したがって、この目的に適したコマンドの接続/順序はeval許可されます。

バッシュ>= v5.1

Bash は配列変数 PROMPT_COMMAND の値をチェックします。
各キーチップを印刷する直前。

PROMPT_COMMANDの要素が設定されていて空でない場合
すでに実行されているように、各値を番号順に実行します。
コマンドラインに入力してください。
...
この変数が設定されて配列の場合、各変数の値は
set 要素は実行されるコマンドとして解釈されます。
メインプロンプト($ PS1)を印刷する前。

設定されているが配列変数ではない場合、その値が使用されます。
実行されるコマンドとして。

どういう意味ですか?

言い換えれば、bashは次のようにほぼ同じことを行います。

if [[ ${#PROMPT_COMMAND[@]} -gt 1 ]]; then
    for cmd in "${PROMPT_COMMAND[@]}"; do eval "${cmd:-}"; done
else
    eval "${PROMPT_COMMAND:-}"
fi

つまり、配列の各要素はeval独立しています。

コミュニティは何をしていますか?

検索"PROMPT_COMMAND"githubに表示されます:

  • 通常、コミュニティでは;区切り文字として使用されます。
  • 場合によっては$'\n'区切り文字として使用されます

具体的に見たことは

いくつかの逸話の注意:

実際に働く様子を見てみましょう

まず、新しいBash v3.2環境を構築しましょう。

docker run -it --rm bash:3.2
bash-3.2$ 

セミコロンで区切られた文字列

- で区切られた文字列を使用してテストすると、;次のようになります。

bash-3.2$ PROMPT_COMMAND='printf 1;printf 2;printf 3;printf ":\n"'
123:
bash-3.2$ 

行で区切られた文字列

- で区切られた文字列を使用してこの結果をテストします\n

bash-3.2$ PROMPT_COMMAND=$'printf 1\nprintf 2\nprintf 3\nprintf ":\n"'
123:
bash-3.2$ 

両方混ぜる

両方の区切り記号を混在させることはできますか?うん! :

bash-3.2$ PROMPT_COMMAND=$'printf 1;printf 2\nprintf 3;printf ":\n"'
123:
bash-3.2$ 

配列はどうですか?

私たちが行くところでは、Bash v5.1が必要です。

docker run -it --rm bash:5.1
bash-5.1$ 

リテラル配列

リテラル配列を使用してこの結果をテストします。

bash-5.1$ PROMPT_COMMAND=( "printf 1" "printf 2" "printf 3" "printf ':\n'" )
123:
bash-5.1$ 
3つすべて試してみてください!

みんな混ぜるとどうなりますか?

bash-5.1$ PROMPT_COMMAND=( "printf 1" $'printf 2\nprintf 3' 'printf 4;printf ":\n"' )
1234:
bash-5.1$ 

どちらを使用しますか?

${PROMPT_COMMAND}配列の場合は、配列にコマンドを追加/追加する必要があります。

(注)必要に応じて、コマンドグループ(単一の文字列や区切り文字列など;$'\n'を配列に個別の項目として追加できます。

${PROMPT_COMMAND}配列でない場合は、次のことを行う必要があります。おそらく;より正式な区切り記号のように感じるので、コマンドを追加するときに使用してください。ただし、追加するコマンドは、$'\n「.」で区切られたステップを含むことができるより複雑なスクリプトである可能性があることに注意してください。

咀嚼機能を試してみますか?

確かに!

##
# pc_munge munges PROMPT_COMMAND.
# Tries to accommodate when PROMPT_COMMAND is an array (supported in Bash v5.1+).
# If ${#PROMPT_COMMAND[@]} has 2+ elements, then we treat as an array, otherwise
# we defensively treat it as a string.
# By default, uses ';' as separator.
#
# NOTE: Does NOT check if command is already present
#
# Parms:
#  $1 command to add
#  $2 before | after (default: after)
#  $3 separator (default: ';')
#
pc_munge() {
    [[ -n "$1" ]] || return
    local fs="${3:-;}" # null | '' => default
    case "${2:-after}" in
        before)
            [[ ${#PROMPT_COMMAND[@]} -gt 1 ]] && PROMPT_COMMAND=( "$1" "${PROMPT_COMMAND[@]}" ) || PROMPT_COMMAND="${1}${PROMPT_COMMAND:+${fs}$PROMPT_COMMAND}"
            ;;
        *) # after
            [[ ${#PROMPT_COMMAND[@]} -gt 1 ]] && PROMPT_COMMAND+=( "$1" ) || PROMPT_COMMAND="${PROMPT_COMMAND:+$PROMPT_COMMAND${fs}}${1}"
            ;;
    esac
}

[編集: スペル エラー "PROMP_" => "PROMPT_"]

[編集: 太字"Som" => "一部"]

[編集:"歌う"スペルエラー=>"シングル"]

おすすめ記事