"#!/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'

오류 없이 실행됩니다. 두 번째 코드가 첫 번째 코드와 동일하면 안 되나요? 왜 첫 번째 오류가 발생합니까?

답변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]합니다 . 문자 코드 순서로 먼저 옵니다 (범위에는 0을 제외한 모든 숫자, 모든 대문자, 일부 특수 문자가 포함됩니다). 그러나 사용 중인 로케일 에서는 정렬이 before 이므로 범위가 유효하지 않습니다.\d1\1\en_US.UTF-8\1

두 번째 스크립트에서:

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

POSIXLY_CORRECTShell에서 설정 하더라도 내보내기가 되지 않아 POSIXLY_CORRECT환경 없이 sed를 호출하고, GNU 확장을 사용하여 sed를 실행합니다.

export POSIXLY_CORRECT두 번째 스크립트의 상단 근처에 추가 하면 sed 불평도 표시됩니다.

관련 정보