「#!/bin/sh -a」の-aはsedに影響しますが、「set -a」が影響しないのはなぜですか?

「#!/bin/sh -a」の-aはsedに影響しますが、「set -a」が影響しないのはなぜですか?

次の.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_variableInvoked 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 なので、範囲は無効です。\d1\1\en_US.UTF-8\1

2番目のスクリプトでは:

#!/bin/sh
set -a
echo "a" | sed -e 's/[\d001-\d008]//g'

POSIXLY_CORRECTShellで設定してもエクスポートできないため、環境なしでPOSIXLY_CORRECTsedを呼び出し、GNU拡張機能を使用してsedを実行します。

export POSIXLY_CORRECT2番目のスクリプトの上部付近に追加すると、sed文句も表示されます。

おすすめ記事