コマンド置換が末尾の改行を削除するのを防ぐエレガントな方法

コマンド置換が末尾の改行を削除するのを防ぐエレガントな方法

zsh をカスタマイズし、環境変数の状態に応じて文字列であってもなくてPROMPTもよい関数を呼び出します。echo

function my_info {
    [[ -n "$ENV_VAR"]] && echo "Some useful information\n"
}

local my_info='$(my_info)'

PROMPT="${my_info}My awesome prompt $>"

情報が末尾の改行で終わって情報が設定されている場合は、自分の行に表示したいと思います。

Some useful information
My awesome prompt $>

ただし、設定されていない場合は、プロンプトが無条件に改行されて空行が発生するのを防ぐために、プロンプトを1行に表示したいと思います。

PROMPT="${my_info}  # <= Don't want that :)
My awesome prompt $>"

現時点では、$(command substitution)改行文字の後に印刷されない文字を追加して改行文字を削除する問題を解決しているため、改行文字は後に来ません。

[[ -n "$ENV_VAR"]] && echo "Some useful information\n\r"

これは明らかにハッキングです。改行で終わる文字列を返すきちんとした方法はありますか?

編集する:わかりました。末尾の改行が失われる原因そしてなぜこれが起こるのですか?しかし、この質問では、特にこの動作を防ぐ方法を知りたいです。このソリューション「条件付き」改行文字を探しているので、私の場合は動作します。)

編集する:修正します。参照ソリューション実際にはかなり良い解決策かもしれませんが、(比較では文字列の前にプレフィックスを付けるのは一般的で、やや似たようなパターンなので)うまくいくことはできません。

echo "Some useful information\n"x
  [...]
PROMPT="${my_info%x}My awesome prompt $>"

x私のために末尾を削除しません。

編集する:急速な拡張という奇妙な問題を解決するために、提案された解決策を適用した結果、次のような結果が出ました。

function my_info {
    [[ -n "$ENV_VAR"]] && echo "Some useful information\n"x
}

local my_info='${$(my_info)%x}'

PROMPT="$my_info My awesome prompt $>"

これが元のソリューションよりも優れたソリューションであることがわかります。もう少し明確だと思いますが、読みやすさが落ちる感じもします。

ベストアンサー1

最後の改行文字はコマンド置換から削除されます。 zshでさえ、これを防ぐためのオプションを提供しません。したがって、最終改行文字を維持するには、最終改行文字にならないように配置する必要があります。

最も簡単な方法は、正確に取得したいデータの後に追加の文字(改行を除く)を印刷し、コマンド置換の結果から最後の追加文字を削除することです。対応する追加文字の後に改行を追加することを選択できますが、とにかく削除されます。

zshでは、コマンド置換と文字列操作を組み合わせて不要な文字を削除できます。

my_info='${$(my_info; echo .)%.}'
PROMPT="${my_info}My awesome prompt $>"

あなたのシナリオでは、これはmy_infoコマンドの出力ではなく出力を取得するために使用されるシェルの断片であり、プロンプトが拡張されたときに評価されます。変数の値から最終値を削除しよPROMPT=${my_info%x}…うとするため、機能しませんが終了します。xmy_info)

他のシェルでは、これは2つのステップで行われます。

output=$(my_info; echo .)
output=${output%.}

my_infoBashではから直接呼び出すことはできませんPS1。から呼び出す必要がありますPROMPT_COMMAND

PROMPT_COMMAND='my_info=$(my_info; echo .)'
PS1='${my_info%.}…'

おすすめ記事