いまごろになって、メタキャラクタのエスケープ処理を、自分はきちんと理解できてないなぁ、と思うことがあります。
メタキャラクタというのは、
- 「'」(シングルクォート)
- 「"」(ダブルクォート)
- 「\」 (バックスラッシュ、場合によっては¥マーク)
- 「$」(ドル)
など、単なる記号文字として以外にも、何か別の意味ありげな機能を持っている文字のことです。
何か別の意味ってのは、たとえば、シェルのコマンドライン上で、「$」を使った場合、
% echo $LANG
C
というように、「$LANG」と書くと、変数LANGの値へと展開されます。
エスケープ処理というのは、たとえばこの「$」の機能を無効化することです。
ひとつの方法としては、「'」で囲んでやることで
% echo '$LANG'
$LANG
というように、「'」で全体を囲むと、「$」がそのまま出てきます。
エスケープ処理の方法は、何通りもあることがあり、たとえば「\」を使っても、同じ結果が得られます。
% echo \$LANG
$LANG
このエスケープ処理なんですが、けっこう間違えやすくて、やっかいものです(そう思ってるのは、私の技量不足とか、思慮が足りないとか、ダメダメだとか・・・)。
たとえば、「"」をエスケープしたいと思った場合、
/bin/sh の場合
$ echo "aaaa\"hoge\"bbbb"
aaaa"hoge"bbbb
なんていう風に書くことができます。
ところが、/bin/csh の場合、同じようにやっても
% echo "aaaa\"hoge\"bbbb"
Unmatched ".
と、エラー扱いされてしまいます。ツールによって、メタキャラクタの働き方が微妙に違うんですよね。この、「ツールによって解釈が違う」ってのが、ものすごくやっかいだと思います。
「'」(シングルクォート)は、たいてい、かなり強力にエスケープしてくれるんですが、「'」で囲まれた中に「'」を書けないんですよね。
/bin/sh の場合
$ echo 'aaaa\'hoge\'bbbb'
> ・・・まだコマンド文字列の続きだと思われてしまっている。
/bin/csh の場合
% echo 'aaaa\'hoge\'bbbb'
Unmatched '.
「'」をそのまま出したいだけなら、たとえば、ダブルクォートの中に、シングルクォートを書くと、できちゃいます。
/bin/sh の場合
$ echo "aaaa'hoge'bbbb"
aaaa'hoge'bbbb
/bin/csh の場合
% echo "aaaa'hoge'bbbb"
aaaa'hoge'bbbb
なんかもう、こういうルールを何個も覚えなくちゃならないかと思うと、頭が混乱してきます。
PHPで、PostgreSQLを使うスクリプトを書いているとき、SQL文を書くときに、どういうわけか、ときどき、「\\\\」と、「\」を4個も重ねて書かなくてはならないときがあって、あーもー何がなんだか と思うことがあります。
この前やった失敗は、途中で「"」が消えてなくなると思って書いてたら、意に反して、最後まで「"」が生き残って、その結果、データベースに、「"Hello world"」のように、「"」がついたまま、文字列が登録されてた、とか
ある文字集合を使っているときに、エスケープ文字も同じ文字集合に含まれているために、こういうやっかいなことになるわけだから、もしもエスケープ文字が、別の文字集合から持ってこれたらいい、でも別の文字集合を使うときは、また別の別の文字集合からエスケープ文字を持ってきて、・・・あーもー何が何だか