次の.shファイルを実行すると:
#!/bin/sh -a
echo "a" | sed -e 's/[\d001-\d008]//g'
結果はエラーです:
sed: -e 式 #1、文字 18: 無効な範囲の終わり
しかし、次の.shファイルを実行すると:
#!/bin/sh
set -a
echo "a" | sed -e 's/[\d001-\d008]//g'
エラーなしで実行されます。 2番目のコードは1番目のコードと同じではありませんか?なぜ最初のエラーが発生するのですか?
答え1
bashがnameで呼び出されるとsh
、これを行う:
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
Invoked 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では文字のエスケープコードで、ベース10の値は次のとおりです。\dNNN
ニューラルネットワークただし、POSIXモードでは角かっこ式内で無効になるため、文字通りからまでの文字などを意味します[\d001-\d008]
。文字コード順に最初に来ます(範囲には、ゼロを除くすべての数字、すべての大文字、いくつかの特殊文字が含まれます)。ただし、使用中のロケールではソートが before なので、範囲は無効です。\
d
1
\
1
\
en_US.UTF-8
\
1
2番目のスクリプトでは:
#!/bin/sh
set -a
echo "a" | sed -e 's/[\d001-\d008]//g'
POSIXLY_CORRECT
Shellで設定してもエクスポートできないため、環境なしでPOSIXLY_CORRECT
sedを呼び出し、GNU拡張機能を使用してsedを実行します。
export POSIXLY_CORRECT
2番目のスクリプトの上部付近に追加すると、sed文句も表示されます。