tcsh와 다른 쉘 간의 일관성 없는 stderr 리디렉션

tcsh와 다른 쉘 간의 일관성 없는 stderr 리디렉션

tcsh에 리디렉션 문제가 있습니다.

다음 명령을 고려하십시오: vi --versionvi --xxx. 우리는 이것이 vi--version옵션을 지원하는 머신에 있다고 가정합니다. 이 옵션은 --xxx아무런 효과가 없으므로 를 vim통해 무언가가 표시되어야 합니다 stderr.

이러한 추론에 따라 2> /dev/null이 두 명령과 함께 사용하면 유효한 경우에는 출력을 제공하고 잘못된 경우에는 출력을 제공하지 않아야 합니다.

그 다음에bash, zsh, ksh 및 dash에서 본 것입니다.

$ vi --xxx 2> /dev/null
$ vi --version 2> /dev/null
VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Oct 20 2014 16:09:17)
...

그러나 tcsh에서 이것을 시도하면 나에게 제공됩니다.출력 없음존재하다둘 다사례.

$ vi --xxx 2> /dev/null
$ vi --version 2> /dev/null
(there is no output here)

여기서 무슨 일이 일어나고 있는 걸까요? 내가 stderr잘못 방향을 바꾸고 있는 걸까?

출력은 다음과 같습니다 tcsh --version.

tcsh 6.18.01 (Astron) 2012-02-14 (i686-intel-linux) options wide,nls,dl,al,kan,rh,nd,color,filec

답변1

이러한 불일치는 실제로 이유 목록의 첫 번째 이유입니다.유해한 것으로 간주되는 csh 프로그래밍.

아니면 stderr을 버리고 stdout을 유지하고 싶다면 어떻게 해야 할까요? 조작법은 아주 간단하죠?

cmd 2>/dev/null

Bourne 쉘에서 작업합니다. csh에서는 다음과 같은 한심한 시도만 할 수 있습니다.

(cmd > /dev/tty) >& /dev/null

그런데 누가 stdout이 내 tty라고 말했습니까? 그래서 이것은 잘못된 것입니다. 이 간단한 조작완료할 수 없습니다csh에서.

답변2

2>은(는) 의 연산자가 아니며 해당 연산자를 tcsh사용하고 이를 매개변수로 전달합니다 . 이것>2vi나타나다괜찮아요. 왜냐하면 --xxx그리고 --version나가기 때문이죠 vi.

에서 tcsh(1):

   > name
   >! name
   >& name
   >&! name
           The file name is used as standard output.  If the file does not
           exist then it is created; if the file exists, it is  truncated,
           its previous contents being lost.

           If  the shell variable noclobber is set, then the file must not
           exist or be a character  special  file  (e.g.,  a  terminal  or
           `/dev/null')  or an error results.  This helps prevent acciden‐
           tal destruction of files.  In this case the `!'  forms  can  be
           used to suppress this check.

           The  forms  involving  `&' route the diagnostic output into the
           specified file  as  well  as  the  standard  output.   name  is
           expanded in the same way as `<' input filenames are.

그래서 당신은 >&리디렉션을 사용할 수 있습니다둘 다표준 출력 및 표준 오류("진단 출력"). "명백한" 방법은 없습니다오직C 셸의 오랜 단점인 stderr를 리디렉션하는 잘 알려진 해결 방법은 다음과 같습니다.

(vi --xxx > /dev/tty) >& /dev/null

이는 /dev/tty서브셸에서 stdout을 (현재 tty)로 리디렉션하여 수행되며(괄호는 본 쉘에서와 동일하게 작동함) 서브셸의 출력(stdout을 리디렉션했기 때문에 stderr만 해당)으로 리디렉션됩니다 /dev/null. 파일 등 무엇이든 가능합니다).

나는 당신의 목표가 무엇인지 모르지만 사용자가 어떤 쉘을 사용하고 있는지 알 수 없는 상황에서는 일반적으로 Fish와 같은 "bourne 및 csh"보다 더 많은 쉘이 있음을 명시적으로 설정하는 것이 더 낫다는 것을 알았습니다. Bourne 쉘 사이에 약간의 비호환성이 있을 수도 있고 특정 구성이 한 쉘에서는 작동하지만 다른 쉘에서는 작동하지 않을 수도 있습니다.

관련 정보