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


20

次の.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が同じというわけではありません。すべてのsedも同等ではありません。どちらshを使用していますか?どのOSで?そして、どのsed(たぶんsed --version失敗しない場合は?)
アイザック

1
問題を回避するための呼び出しの設定LC_COLLATE=C(またはPOSIXsed
ジェフシャラー

4
私が見つけた1つの違い:最初のスクリプトはsed(およびおそらく他のユーティリティ)をPOSIXLY_CORRECT=y環境内で呼び出しますが、2番目のスクリプトは環境内にありませんPOSIXLY_CORRECT。両方のスクリプトを呼び出すシェルはPOSIXLY_CORRECT、その環境にはありません。
マークプロトニック

1
ああ、echo "a" | POSIXLY_CORRECT=y sed -e 's/[\d001-\d008]//g' 問題を再現してください
Isaac

1
OPがCentOS 7.x-GNU bash、バージョン4.2.46(2)-release(x86_64-redhat-linux-gnu)およびCentOS Linux release 7.5.1804(Core)で示したとおり、上記の操作が失敗することを確認します。
slm

回答:


31

bashが名前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呼び出しbind_variable_internalaその時点でシェル属性がオンの場合(シェルをで起動した場合-a)、シェル変数をexportとしてマークします

最初のスクリプトでは:

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

sedPOSIXLY_CORRECT=yその環境でが呼び出されます[\d001-\d008]。(sedに--posixオプションが与えられた場合も同じことが起こります。)

GNUはsedのでは、数値の文字のエスケープコードであるベースは、10であるNNNが、POSIXモードでは、これはそう、ブラケット表現内の無効化され、文字通り手段文字、範囲からのもので、等へ。文字コードの順で、前に来ます(範囲には、ゼロを除くすべての数字、すべての大文字、およびいくつかの特殊文字が含まれます)。ただし、使用していたロケールでは、の前にソートされるため、範囲は無効です。\dNNN[\d001-\d008]\d1\1\en_US.UTF-8\1

2番目のスクリプトで:

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

たとえPOSIXLY_CORRECTシェルに設定されている、そうせずに呼び出されsedは、エクスポートされていないPOSIXLY_CORRECT環境では、とGNUの拡張を実行するsedの。

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


6
私にとって、それはバグです。
ステファンシャゼラス

1
聖なる貝の恐怖、バットマン!これは興味深い癖です(そして/bin/sh実際 Bashであることに起因する問題を見るための少しの変更)。Bashが開始するPOSIXLY_CORRECT前に環境内にある場合も同じことが起こりshます。それはとしても渡されPOSIXLY_CORRECT=yます。
-ilkkachu

3
@StevenPenny、しかしPOSIXLY_CORRECT でないシェルが起動し、スクリプトがそれを設定していないときの環境で。シェルはそうします。環境変数をどこからでも作成しますが、それは本来あるべきモードでそれを行い、標準に準拠しようとするため、非常に悪いです。
-ilkkachu

4
FWIW、BashはまたPOSIXLY_CORRECT、独自に設定することを文書化していないようです。POSIXモードの効果のリストにはそれについての言及はなく、変数の説明は、それを設定するとシェルがPOSIXモードに変更されることのみを示しており、逆にはなりません。
-ilkkachu

1
@ilkkachu。できた 影響を受ける変数を明確にするために、POSIX仕様も更新する必要があると思いますallexport
ステファンシャゼラス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.