Bashでの変数置換のバックスラッシュ

Bashでの変数置換のバックスラッシュ

ハードドライブを正しく分割するのに役立つBashスクリプトを作成していますが、変数に数字を追加する必要がある奇妙な問題が発生しました。私はBashの経験があまりないので、正しい結果を得るのに少し時間がかかりましたが、一時的に何かをすることができました。

以下は、私が構築している作業の例です。

#!/bin/bash

devName="/dev/sda"
devTarget=$devName\3

echo "$devTarget"

これdevNameは変数ですが、/dev/sda後でスクリプト内の3番目のパーティションの変数も設定する必要があるため、表記法を使用しました。\これにより、数値を追加して出力を生成すること3ができました。/dev/sda/dev/sda3

表記はうまくいきますが、\これがこのようなことをする正しい方法であるかどうか疑問に思います。 Pythonでは、引用符などの次の文字を無視するために使用されたため、これを使用していますが、この場合はその逆を実行したかったので、驚くほどうまくいきます。これが変数を追加する最良の方法ではない場合、誰かがBashでこれを行う最良の方法の例を示すことができますか?

答え1

文字列に変数を挿入する安全な方法はを使用することです${var_name}

#!/bin/bash

devName="/dev/sda"
devTarget="${devName}3"

echo "$devTarget"

このように、Bashはどの変数が挿入されるのか疑いません。

devTarget=$devName\3しかし、それがどのように機能するのか面白いです。理由はわかりません。

答え2

$x\b同じように動作する$x"b"か、"$x"b変数名を引用符で囲むことで動作します。他に理由がなければ、変数が拡張されたときに引用符がまだ残っていて、\"'有効な変数名がないため、これが起こると思います。

これ標準テキスト説明する:

単語拡張の順序は次のとおりです。

1. ...、パラメータ拡張(パラメータ拡張を参照)、...

4. 見積もりの​​削除(見積もりの​​削除を参照)は、常に最後に実行する必要があります。

そして、「引用符の削除」は実際に引用符を削除するステップです。

しかし@tomaszが言ったように彼らの答えに、変数名を中かっこ内に入れるのが一般的なので"${x}b"、 または です"${devName}3"。ほぼ常に拡張子の周りに引用符を付けたいです。いつ二重引用符が必要ですか?

(しかし、実際に引用符文字を保存するだけでなく、プログラムで引用符付き文字列を表示する別の方法があるかどうか疑問に思います。)

答え3

スクリプトが示すのは、出力に変数と数字を書き込んでいることです。とても簡単です。printfフォーマット文字列を使用して、次のことを達成できます。

$ devName="/dev/sda"
$ printf "%s%d\n" "$devName" 3
/dev/sda3

しかし、あなたが言ったように使用-vスクリプトの後半の新しい変数を使用すると、バージョンのフラグを利用することもできます。bashprintf

$ printf -v devTarget "%s%d" "$devName" 3
$ echo "$devTarget"
/dev/sda3

この方法は機能しませんPOSIX-vこれはprintfであり、他のシェルでは動作しません(少なくともkshとmkshにはprintfのフラグがなく、zhshについてはわかりません)。したがって、コマンドの置き換えによってこの問題を解決できます。

$ devTarget=$(printf "%s3" "$devName")

しかし、受け入れられた回答よりシンプルで携帯性が良いかもしれません。

答え4

〜のようにトーマスは指摘した、変数名を構成する文字を正確に指定する正しい方法は、中かっこを使用することです${devName}3

Bashを使用すると、便宜のために中括弧を省略できますが、そうすると、参照する変数に対して完全に明示的な機能が失われます。 Bashがこの問題を解決する方法は、ドル記号で始まる最も長い有効な変数名を使用することです。変数名は文字またはアンダースコアで始まり、文字、数字、アンダースコアを任意に含めることができますが、他の文字は含めることはできません。したがって、あなたの例では、$devName\3bashはで始まり、見つけることができるd最も長い文字/数字/下線文字を探しますdevName。これは使用する変数の名前として機能します。同様に、同様のものは名前付き変数を$here-is-a-long-string-of-words使用しますhere。それは次のようになります${here}-is-a-long-string-of-words

次に、bashは\3バックスラッシュが次の文字を特別な意味なしに正常に解釈できるようにする引用形式であることを確認します。しかし、3とにかく特別な意味はないので、バックスラッシュは重複します。このシーケンスは最終的に別のシーケンスと同じです3

関連情報