次の.shファイルを実行すると、
#!/bin/sh -a
echo "a" | sed -e 's/[\d001-\d008]//g'
結果はエラーです:
sed:-e expression#1、char 18:無効な範囲の終わり
しかし、次の.shファイルを実行すると、
#!/bin/sh
set -a
echo "a" | sed -e 's/[\d001-\d008]//g'
エラーなしで実行されます。 2番目のコードは最初のコードと同等ではないのですか?なぜ最初のエラーですか?
sh
という名前でbashが呼び出されると、 はこれを実行します :
if (Shell_name[0] == 's' && Shell_name[1] == 'h' && Shell_name[2] == '\0')
act_like_sh++;
その後 はPOSIXLY_CORRECT
シェル変数をy
に設定します:
if (act_like_sh)
{
bind_variable ("POSIXLY_CORRECT", "y", 0);
sv_strict_posix ("POSIXLY_CORRECT");
}
bind_variable
は、bind_variable_internal
を呼び出します。これは、シェル属性a
がオンの場合(-a
でシェルを呼び出した場合)、 シェル変数をエクスポート済みとしてマークします。 。
したがって、最初のスクリプトでは:
#!/bin/sh -a
echo "a" | sed -e 's/[\d001-\d008]//g'
sed
は、その環境でPOSIXLY_CORRECT=y
を使用して呼び出されます。これにより、[\d001-\d008]
について不満が出ます。 (sedに--posix
オプションが指定されている場合も同じことが起こります。)
GNU sedでは、\dNNN
は、base-10の数値が NNN、ただしPOSIXモードでは、これは角括弧式内では無効になっているため、[\d001-\d008]
は文字通り\
、d
などの文字を意味し、範囲は1
から\
です。文字コードの順序では、1
は\
の前にあります(範囲には、ゼロを除くすべての数字、すべての大文字、およびいくつかの特殊文字が含まれます)。ただし、使用していたen_US.UTF-8
ロケールでは、\
は1
の前にソートされるため、範囲は無効です。
2番目のスクリプトでは:
#!/bin/sh
set -a
echo "a" | sed -e 's/[\d001-\d008]//g'
シェルでPOSIXLY_CORRECT
が設定されている場合でも、エクスポートされないため、環境でPOSIXLY_CORRECT
なしでsedが呼び出され、sedはGNU拡張機能で実行されます。
2番目のスクリプトの上部近くにexport POSIXLY_CORRECT
を追加すると、sedのクレームも表示されます。