다음 .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_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]
합니다 . 문자 코드 순서로 먼저 옵니다 (범위에는 0을 제외한 모든 숫자, 모든 대문자, 일부 특수 문자가 포함됩니다). 그러나 사용 중인 로케일 에서는 정렬이 before 이므로 범위가 유효하지 않습니다.\
d
1
\
1
\
en_US.UTF-8
\
1
두 번째 스크립트에서:
#!/bin/sh
set -a
echo "a" | sed -e 's/[\d001-\d008]//g'
POSIXLY_CORRECT
Shell에서 설정 하더라도 내보내기가 되지 않아 POSIXLY_CORRECT
환경 없이 sed를 호출하고, GNU 확장을 사용하여 sed를 실행합니다.
export POSIXLY_CORRECT
두 번째 스크립트의 상단 근처에 추가 하면 sed 불평도 표시됩니다.