環境変数の前の\の意味

環境変数の前の\の意味

古い Solaris ボックスの ksh では、次を使用しました:

export PS1="$PWD $"

プロンプトを現在のディレクトリに設定します。他の場所に cd するまではうまく動作しますが、その後は毎回 PWD を評価していないことがわかります。代わりに PS1 を次のように設定すると修正されることがわかりました。

export PS1="\$PWD $"

それが何と呼ばれているのか、どのように機能するのか、他の用途などについて知りたいだけです。(これは Google 検索でなかなか見つからないものの 1 つです。)

答え1

これを説明するには、いくつかのドキュメントが役立ちます。

からシェルのPOSIX標準文書:

以下の変数は、シェルの実行に影響します:
PS1: 対話型シェルがコマンドの読み取り準備ができるたびに、この変数の値がパラメータ展開され、標準エラーに書き込まれます。
...
一重引用符
一重引用符で囲まれた文字は、一重引用符内の各文字のリテラル値を保持します。
...
二重引用符
二重引用符で囲まれた文字は、$ を除き、二重引用符内のすべての文字のリテラル値を保持します
。ドル記号は、パラメータ展開を導入する特別な意味を保持します
。 ...
エスケープ文字 (バックスラッシュ) 引用符
で囲まれていないバックスラッシュは、次の文字のリテラル値を保持します。

したがって、 の値はPS1パラメータ展開の対象となり、これが必要なので、プロンプトが表示されるたびに評価されます。つまり、の値には$PWD実際の文字列が必要です。しかし、$PWDPS1

PS1="$PWD $ "

の価値を置くPWD 代入文が実行された時点でにするとPS1PS1のようになり/home/poldie $、その後は変更されません。これは望ましくありません。

PS1="\$PWD $ "

バックスラッシュは を引用符で囲むので$、 にはPS1リテラル文字列 が含まれます$PWD $。これが必要です。

PS1='$PWD $ '

同じことを行います。パラメータは一重引用符で囲まれている場合は展開されません。

export(注: OP がステートメントとして記述することを選択したため、私はもともとこれらすべてをステートメントとして記述していましたexport。@Kusalananda がそれらを削除しました。理由はわかりません。子シェル (vi のコマンドによって生成されたものなど:sh) でカスタム プロンプトを保持する場合は、PS1 をエクスポートすることが有効な選択肢です。)

答え2

文字\は、後続の (特殊) 文字をエスケープします。この場合、 は、$通常、変数の参照解除に使用する をエスケープします。シェルが変数割り当てを評価する場合、最初に式の右側を展開します。 が前にない場合\$PWDシェルは を展開して$PWD、結果を に割り当てますPS1

しかし、 の場合、\シェルは を$PWDリテラル文字列として扱い、それを にそのまま割り当てますPS1。そのため、 にはPS1文字列 が含まれ$PWD、変数 の展開された値は含まれません$PWD。シェルがプロンプトを表示しようとすると、再び変数の展開が行われます。今回は に$PS1は が含まれるため$PWDなしで\シェルはそれを現在のディレクトリに正常に展開します。

同じアプローチを使用して、シェル スクリプトで動的な変数名を作成することもできます (NetBSDrcNGシステムでは、特にネットワーク インターフェイスを制御するスクリプトでこれを広く使用しています。NetBSD と FreeBSD ではネットワーク アダプターの指定の数が多いため、それぞれを明示的にコード化するのは非現実的です)。

関連情報