POSIX 스크립트에서 x=$y는 항상 x="$y"와 동일합니까?

POSIX 스크립트에서 x=$y는 항상 x="$y"와 동일합니까?

x=$y

그리고

x="$y"

그들은 항상 동등합니까? 이것을 찾는 방법을 잘 모르겠습니다. 지금까지 나는 x="$y""안전하게 플레이"하는 데 익숙했습니다. 그러나 나는 x=$1분명히 여분의 큰따옴표가 필요하지 않다는 것을 사용하고 알아차렸습니다.

Open Group POSIX 문서에서 동작은 어디에 정의되어 있습니까?

답변1

예, POSIX 셸에서도 동일하다는 것이 보장됩니다 x=$y. x="$y"귀하 또는 다른 코드 독자가 큰따옴표가 어디에 있는지 확실하지 않은 경우~ 해야 하다사용됩니다(참조언제 큰따옴표가 필요합니까?), 큰따옴표를 포함하는 것이 혼란을 피하기 위해 더 안전한 선택일 수 있습니다.

POSIX 사양에서 (2.9.1절. “간단한 명령”):

주어진 간단한 명령을 실행해야 하는 경우 [...] 다음 확장, 할당 및 리디렉션이 명령 텍스트의 처음부터 끝까지 수행되어야 합니다.

  1. 다음 규칙에 따라 변수 할당 또는 리디렉션으로 식별되는 단어쉘 구문 규칙3단계와 4단계의 처리를 위해 저장합니다.

[...]

  1. 리디렉션은 다음에 설명된 대로 수행되어야 합니다.리디렉션.
  2. 물결표 확장, 매개변수 확장, 명령 대체, 산술 확장 및 따옴표 제거를 할당하기 전에 모든 변수 할당을 확장해야 합니다.

네 번째 항목에는 다음이 포함되지 않습니다.필드 분할또는경로명 확장("globbing"), 종종 단어가 나타날 때 발생하는 확장의 일부아니요변수 할당으로 인식됩니다. 할당 시 이러한 단계가 제거되므로 참조가 필요하지 않습니다.

당신은 또한 볼 수 있습니다섹션 2.6 “단어 확장”:

단어 확장 순서는 다음과 같습니다.

  1. 물결표 확장(참조물결표 확장), 매개변수 확장(참조매개변수 확장), 명령 대체(참조명령 대체) 및 산술 확장(참조산술 확장)은 처음부터 끝까지 실행되어야 합니다. 항목 5 참조토큰 인식.
  2. 필드 분할(참조필드 분할)은 null이 아닌 한 1단계에서 생성된 필드 부분에 대해 수행되어야 합니다 IFS.
  3. 경로명 확장(참조경로명 확장set -f)은 효력이 발생하지 않는 한 시행됩니다 .
  4. 참조 제거(참조견적 삭제)은 항상 마지막에 실행되어야 합니다.

y다음은 in x=$yx="$y"가 실제로 특수 인수 중 하나 인 경우에만 중요합니다 .*@

"$@"다음으로 확장되므로 참고하세요.목록문자열의 경우 what x=$@x="$@"do가 지정되지 않지만 x=$*와 동일합니다 x="$*". 일부 쉘(예: bash, ksh93) 에서는 $@의 첫 문자가 공백인 경우와 동일하게 사용되는 반면, 다른 쉘(예: busybox, , )에서는 설정 값의 첫 번째 문자를 사용하는 경우와 동일합니다.$*$IFSshdashzsh$*$IFS

답변2

일반적으로 다음과 같은 것들이 있습니다.변수를 정의할 수 있는 섹션입니다.

  • 선행 변수 할당

    대시보드 매뉴얼에는 간단한 명령이 설명되어 있습니다.

    "name=value" 형식의 선행 단어가 제거됩니다.

    즉, x=$y정확히 x="$y".

    즉,2.9.1절. “간단한 명령”토큰화나 경로 이름 확장은 적용되지 않습니다. 이 두 확장자는 새로운 단어를 생성할 수 있는 유일한 확장자이므로 IFS 문자가 포함된 변수를 분할하거나 여러 파일 이름을 일치시키는 것은 불가능합니다. 거기서 한 마디는 x=$y한 마디로 남을 것이다.

  • 나머지 매개변수

    "명령 이름"을 나타내는 단어가 발견되면 구문 분석 변경 및 할당이 분할되어 다른 것이 될 수 있습니다.

    Bash 매뉴얼에서는 이를 다음과 같이 설명합니다.

    할당문은 별칭, 선언, 조판, 내보내기, 읽기 전용 및 로컬 내장 명령(선언 명령)에 대한 인수로 나타날 수도 있습니다.

    아직 인용해야 할 곳이 있습니다. 처럼 declare x="$y".

    물론 POSIX에서는 exportand 만 readonly의미가 있습니다.

    이제 yash에서만 실패합니다.

    $ yash -c 'unset x; y="one two"; readonly x=$y; echo "x=$x"'
    x=one
    

그렇습니다. 일반적으로 x=$y완전히 x="$y"동일합니다 .와는 별개로어떤 경우에는 명령 이름 뒤에 변수 할당이 존재합니다.

관련 정보