シェルスクリプトはコマンド類を組み合わせて処理フローを記述できます。 スクリプトに記述したフローはbashなどのシェルが制御していますが、その過程で変数展開などの文字列処理が走ります。
暗黙の文字列処理は、スクリプトに記述しない部分であるため分かりづらく、とくに入力文字列にクオート類を含む場合に意図しない挙動を簡単に引き起こします。
クオートは文字列の範囲や実行制御を変更し、スクリプトの内容を根本的に変化させるため、回避したいケースが多々あります。
文字列中のクオートが人が目視するだけの目的しかない場合、次のようにsedを用いて見た目が似ている無害な文字に置換する手があります。
sed -e s/[\']/‘/g -e s/[\"]/”/g -e s/[\`]/’/g
サニタイズしたい文字列を標準入力から供給すると、クオートを置換した文字列を出力します。
この例では、シングルクオート・ダブルクオート・バッククオートの3種のASCIIクオート文字を、見た目が似ているUTF-8文字に起き換えています。
bashはこれらのUTF-8文字に特別な機能を持たせていないため、クオートに注意する必要がなくなります。
当然ながら後続の処理ではUTF-8を適切に処理できる必要があります。
また、再び元のクオート類として処理したい場合には逆のデコードが必要になりますが、極力避けた方が良いでしょう。
より複雑なケース
サニタイズした文字列を変数に格納したい場合には、$()
を追加します。
また、スクリプト中に文字列をハードコードしたい場合にはヒアドキュメントを用います。
この2つを組み合わせた例は次のようになります。
#!/bin/bash
SANITIZED_STR=$(sed -e s/[\']/‘/g -e s/[\"]/”/g -e s/[\`]/’/g << '__EOS__'
"<some-hardcoded-string-with-quotes>"
__EOS__
)
⁋ 2024/05/08↻ 2024/12/18
中馬崇尋
Chuma Takahiro
Chuma Takahiro