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

오류없이 실행됩니다. 두 번째 코드는 첫 번째 코드와 동일하지 않습니까? 첫 번째 오류가 왜 발생합니까?


모두 sh같은 것은 아닙니다 . 모든 sed도 동일하지 않습니다. 어느 sh것을 사용하고 있습니까? 어느 OS에서? 그리고 어느 sed ( sed --version실패하지 않습니까?)
Isaac Isaac

1
이 문제를 해결 하기 위해 전화를 걸기위한 설정 LC_COLLATE=C(또는 POSIX)sed
Jeff Schaller

4
내가 찾은 한 가지 차이점 : 첫 번째 스크립트는 환경에서 sed (및 아마도 다른 유틸리티)를 호출하고 두 번째 스크립트는 POSIXLY_CORRECT=y환경에 없습니다 POSIXLY_CORRECT. 두 스크립트를 호출하는 쉘 POSIXLY_CORRECT은 환경에 없습니다 .
Mark Plotnick

1
아, echo "a" | POSIXLY_CORRECT=y sed -e 's/[\d001-\d008]//g' 문제를 재현하라
Isaac

1
OP가 CentOS 7.x-GNU bash, 버전 4.2.46 (2)-릴리스 (x86_64-redhat-linux-gnu) 및 CentOS Linux 릴리스 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_CORRECTy .

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'

sedPOSIXLY_CORRECT=y환경에서 호출되어 에 대해 불평하게됩니다 [\d001-\d008]. (sed에 --posix옵션 이 주어지면 같은 일이 일어난다 .)

GNU가 나오지에서 수치의 문자 이스케이프 코드베이스는 10이다 NNN 하지만 POSIX 모드에서는이 때문에, 브래킷 식 내부 비활성화 , 문자 적 캐릭터 , 범위에서 주도로 등 에 . 문자 코드 순서대로 앞에옵니다 (범위에는 0을 제외한 모든 숫자와 모든 대문자 및 일부 특수 문자가 포함됨). 그러나 사용중인 로캘 에서을 정렬하기 전에 범위가 유효하지 않습니다.\dNNN[\d001-\d008]\d1\1\en_US.UTF-8\1

두 번째 스크립트에서 :

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

POSIXLY_CORRECT쉘에 설정되어 있어도 익스포트되지 않으므로 sed는 POSIXLY_CORRECT환경 없이 호출 되며 sed는 GNU 확장으로 실행됩니다.

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


6
나에게 그것은 버그입니다.
Stéphane Chazelas

1
거대 공포, 배트맨! 즉 (에서 오는 문제 확인 및 변경 약간의 흥미로운 특질 /bin/sh사실 배쉬을). Bash가 시작 POSIXLY_CORRECT되기 전에 환경에있는 경우 sh에도 마찬가지 POSIXLY_CORRECT=y입니다.
ilkkachu

3
@StevenPenny,하지만 POSIXLY_CORRECT 하지 쉘 시작하고, 스크립트를 설정하지 않는 경우 환경에서. 껍질은 않습니다. 그것은 환경 변수를 아무데도 만들지 않습니다. 환경 변수는 예상되는 모드에서 수행하고 표준을 준수하려고 시도하기 때문에 매우 나쁩니다.
ilkkachu

4
Fash, Bash는 POSIXLY_CORRECT자체적으로 설정한다고 문서화하지 않은 것 같습니다 . 에 대한 언급도 없다 POSIX 모드의 효과의 목록변수 설명 만이 그것을 설정하는 것은 POSIX 모드, 다른 방법은 주위에 셸을 변경하는 것을 말한다.
ilkkachu

1
@ilkkachu. 끝난. POSIX 사양도 어떤 변수가 영향을 받는지 명확히하기 위해 업데이트되어야한다고 생각합니다 allexport.
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.