1. ホーム
  2. バッシュ

[解決済み】Bashを使うときにエスケープする必要があるのはどの文字ですか?

2022-04-03 13:40:39

質問

Bashでエスケープする必要がある文字の包括的なリストはありますか?それは sed ?

特に、私がチェックしていたのは % はエスケープする必要があるかどうか。試しに

echo "h%h" | sed 's/%/i/g'

をエスケープすることなく、問題なく動作しました。 % . という意味なのでしょうか? % はエスケープする必要がないのでしょうか?必要性を確認する方法はこれでよかったのでしょうか?

そして、より一般的なことですが、これらの文字は shellbash ?

解決方法は?

に限らず、簡単で安全なルールが2つあります。 sh のみならず bash .

1. 文字列全体を一重引用符で囲む

これは、シングルクォート以外のすべての文字に対して有効です。シングルクォートをエスケープするには、その前のクォートを閉じ、シングルクォートを挿入し、再びクォートを開きます。

'I'\''m a s@fe $tring which ends in newline
'

sedコマンドを使用します。 sed -e "s/'/'\\\\''/g; 1s/^/'/; \$s/\$/'/"

2. すべての文字をバックスラッシュでエスケープする

これは、改行以外のすべての文字に対して有効です。改行文字にはシングルクォートまたはダブルクォートを使用します。 空の文字列を処理する必要があります。 ""

\I\'\m\ \a\ \s\@\f\e\ \$\t\r\i\n\g\ \w\h\i\c\h\ \e\n\d\s\ \i\n\ \n\e\w\l\i\n\e"
"

sedコマンドを使用します。 sed -e 's/./\\&/g; 1{$s/^$/""/}; 1!s/^/"/; $!s/$/"/' .

2b. 2のより読みやすいバージョン

のように、簡単に安全な文字の集合があります。 [a-zA-Z0-9,._+:@%/-] これらはエスケープせずにそのままにしておくと、より読みやすくなります。

I\'m\ a\ s@fe\ \$tring\ which\ ends\ in\ newline"
"

sedコマンドを使用します。 LC_ALL=C sed -e 's/[^a-zA-Z0-9,._+@%/-]/\\&/g; 1{$s/^$/""/}; 1!s/^/"/; $!s/$/"/' .


sedプログラムでは、入力の最終行が改行バイトで終わっているかどうかを知ることができないことに注意してください(空の場合を除く)。そのため、上記の2つのsedコマンドは改行がないものと仮定しています。手動で引用符で囲んだ改行を追加することができます。

シェル変数は、POSIXの意味でのテキストに対してのみ定義されていることに注意してください。バイナリデータの処理は定義されていません。重要な実装では、バイナリはNULバイトを除いて動作しますが(変数はC文字列で実装され、C文字列、すなわちプログラムの引数として使用されることを意図しているからです)、latin1のような"binary"ロケールに切り替える必要があります。


(のPOSIX仕様を読めば、そのルールを簡単に検証することができます)。 sh . bashの場合は 参考マニュアル リンク先:@AustinPhillips)