bash의 `{var}>&1`에 해당하는 zsh 및 POSIX

bash의 `{var}>&1`에 해당하는 zsh 및 POSIX

{var}>&1in 에 해당하는 것이 있습니까 zsh?

이것bash수동설명하다:

각 리디렉션 앞에는 파일 설명자 번호가 올 수 있지만 다음 형식의 단어가 앞에 올 수도 있습니다 {varname}. 이 경우 >&-및 를 제외한 모든 리디렉션 연산자 에 대해 <&-쉘은 10보다 큰 파일 설명자를 할당하고 이를 에 할당합니다 {varname}. >&-또는 <&-앞에 오는 경우 {varname}varname 값은 닫힐 파일 설명자를 정의합니다.

사용법의 예는 STDERR다음 명령에서 캡처됩니다.

{ error=$( { { ls -ld /XXXX /bin | tr o Z ; } 1>&$tmp ; } 2>&1); } {tmp}>&1

zshPOSIX 세계에서 동일한 작업을 수행하는 방법은 무엇입니까?

일반적인 해결책을 찾고 있습니다. 어떻게 해야 합니까?

  • 사용되지 않는 파일 설명자 찾기
  • 시뮬레이션 {var}>&1구문

답변1

개발자 제안에 따라 {var}>...지원 도 추가되었습니다 ksh93. 이 연산자는 복합 명령과 함께 작동하지만 작동하지는 않습니다.bashzshzsh{var}>...zsh

다음 사항도 참고하세요.

cmd 3>&1

fd 3은 cmd다음에만 열려 있습니다.

cmd {var}>&1

동적으로 할당된 fd( 에 저장됨)는 $var및 에 반환된 후에도 열린 상태로 유지됩니다. 이 연산자는 기본적으로 함께 사용하도록 설계되었습니다(간단한 시스템 호출 인터페이스도 참조).cmdzshbashexecsysopenzshopen()

따라서 위 코드 exec {tmp}>&-에는 bash.

그래서 여기에서 할 수 있습니다:

if exec {tmp}>&1; then
   errors=$(exec 2>&1 >&"$tmp" {tmp}>&- && ls -ld /x /bin | tr o Z)
   exec {tmp}>&-
fi

이것은 에서 작동하며 fd bash를 누출하지 않습니다. (따옴표는 해당 옵션이 활성화되지 않은 경우에만 필요합니다 ). POSIX 모드에서 또는 도중에 실패하면 쉘이 종료됩니다(여기서 실패는 stdout이 닫히거나 열린 파일 수에 대한 제한에 도달했거나 종료하려는 기타 병리학적 조건으로 인해 발생할 수 있음).zshksh93$tmpbashposixksh93zshbashexecdup()

하지만 여기서는 동적으로 할당된 fd가 필요하지 않으며 해당 코드에서 사용되지 않는 fd 3을 사용하면 됩니다.

{ errors=$(exec 2>&1 >&3 3>&-; ls -ld /x /bin | tr o Z); } 3>&1

이것은 Bourne과 같은 쉘에서 작동합니다.

위의 동적 fd 메서드와 마찬가지로 명확하지 않더라도 dup2()(in ) 실패하면 3>&1할당이 실행되지 않으므로 errors이전에 초기화되었는지 확인하는 것이 좋습니다(예: unset -v errors).

fd 3이 다른 방법으로 열리거나 스크립트의 나머지 부분에서 사용되는지는 중요하지 않습니다(열면 원본 fd는 그대로 유지되고 마지막에 복원됩니다). 중요한 것은 포함된 코드가 내부적으로 $(...)fd 3을 예상하는지 여부입니다. 열려 있는 .

fd 0, 1, 2만 응용 프로그램에서 열릴 것으로 예상되며 다른 fd는 열리지 않습니다. ls그리고 trfd3에게 아무것도 기대하지 마세요. 다른 fd를 사용해야 하는 상황은 다음과 같습니다.분명히fd를 사용하고 if와 같이 미리 열려 있을 것으로 예상하는 대신 fd 3이 스크립트에서 더 일찍 열렸을 것으로 예상되는 리소스가 ls있습니다 .cat /dev/fd/3

POSIX 쉘에서 첫 번째 무료 fd를 할당하는 방법에 대한 질문에 대답하려면 POSIX 쉘 및 유틸리티 API에는 방법이 없다고 생각합니다. 이것도 말이 안 될 수도 있습니다. 쉘은 자체 API를 방해하지 않는 한 내부적으로 모든 fd를 사용하여 원하는 작업을 수행할 수 있습니다. 예를 들어, fd 11이 지금은 무료이지만 나중에 내부 작업을 위해 쉘에서 사용될 수 있으며 fd 11에 기록하면 동작에 영향을 미칠 수 있습니다. 또한 POSIX sh에서는 fds 0부터 9까지만 작업할 수 있습니다.

관련 정보