다른 명령을 실행하는 명령에 대한 표준이 있으며 쉘 구조가 어떻게 리디렉션으로 간주될 수 있습니까?

다른 명령을 실행하는 명령에 대한 표준이 있으며 쉘 구조가 어떻게 리디렉션으로 간주될 수 있습니까?

다음 명령의 기능을 수행하는 쉬운 방법이 있습니까?

watch foo 2>/dev/null | tr ' ' '-'
strace foo 2>/dev/null | tr ' ' '-'
something_else foo 2>/dev/null | tr ' ' '-'    

사물이 어떻게 행동해야 하는지에 대한 공유된 기대가 있습니까 something_else? 이러한 명령(예: 어떤 프로그램의 출력이 리디렉션되는지 등)을 명확하게 할 수 있는 쉘 구조가 있습니까?

답변1

명령 자체는 리디렉션을 처리하지 않습니다. 쉘이 명령을 실행할 새 프로세스를 생성할 때 쉘은 지시에 따라 IO를 설정합니다. 명령 자체는 실행되므로 신경 쓸 필요가 없습니다.

귀하의 something_else명령은 평소대로 출력을 stdout 및 stderr로 보냅니다.

답변2

간단히 말해서:

some_else가 어떻게 작동해야 하는지에 대한 공통된 기대가 있습니까?

예, 상설 명령입니다. 쉘은 두 개의 명령을 이해하지 못합니다. 이는 명령과 인수입니다( command1 command2예를 들어 유효한 바이너리의 이름일 수도 있음). /bin이는 command1나중에 쉘이 아닌 시스템 호출을 command2통해 실행됩니다.exec()

이러한 명령(예: 어떤 프로그램의 출력이 리디렉션되는지 등)을 명확하게 할 수 있는 쉘 구조가 있습니까?

아니요, someting_else특별한 대우를 받지 않습니다. 위에서 언급했듯이 명령과 인수 이외의 구조는 없습니다. 이 문제에 대한 혼란은 다음과 같은 데 있는 것 같습니다.둘 다 strace쉘에 의해 실행되는 것으로 가정 하지만 foo실제로는 상위-하위 프로세스 체인입니다.

쉘이 명령과 리디렉션을 처리하는 방법

Bourne(예: bash, dash, ksh)과 같은 쉘은 모두 명령 해석 방법에 대해 POSIX 규칙을 따릅니다.POSIX 지정: ""간단한 명령"은 임의의 순서로 선택적 변수 할당 및 리디렉션의 시퀀스이며 선택적으로 단어 및 리디렉션이 뒤따르고 제어 연산자에 의해 종료됩니다. 이는 테이블로 작성할 수 있습니다.

[VAR=foo BAR=baz] command1 [arg1, arg2...] [ n>m ]

일반적인 규칙은 대부분의 비할당 단어를 보존하는 명령에 리디렉션이 적용된다는 것입니다. 귀하의 예에서 strace는 명령이고 foo는 인수입니다 strace. 리디렉션은 인수가 아닌 명령에 대해서만 작동합니다. 즉, 쉘에 의해 실행 strace되지 않고 이 경우 하위 프로세스에 의해 실행됩니다 . 이번에도 매개변수가 있는 명령 으로 처리됩니다 .foostracefoostracesomethingelsefoo

파일 설명자

내장되지 않은 명령에 관한 한 해당 명령은 셸의 하위 프로세스이고 하위 프로세스는 셸의 파일 설명자를 상속하므로 일반적으로 리디렉션을 관리하지 않습니다. "미리 패키지된" 대상을 수신하므로 strace현재로서는 2>/dev/null그럴 수 있습니다 . 파일 설명자 2가 실제로 무엇인지는 신경 쓰지 않습니다(소스 코드 수준을 적극적으로 확인하지 않는 한). strace출력은 여전히 ​​파일 설명자 2에 기록되지만 쉘은 해당 파일 설명자를 /dev/null.

strace stat noexist 2>stracelog.txt파일 설명자는 상속되므로 두 오류 스트림에서 이와 같은 작업을 수행 strace하고 stat동일한 파일로 이동하는 이유도 설명됩니다. 이와 대조적으로 일부 명령에서는 대상을 옵션 중 하나로 명시적으로 지정할 수 있습니다. 따라서 파일에 출력만 있습니다 strace -o tracelog.txt stat noexist 2>stracelog.txt. 파일 설명자가 상속되더라도 이제 플래그는 의 속성이고, 파일 설명자가 상속되더라도 출력은 명령으로 관리됩니다.statstracelog.txt-ostrace

이는 또한 약간의 힌트를 제공합니다. 이론적으로 명령은 "리디렉션"될 수 있습니다. 즉, 파일 설명자는 시스템 호출을 통해 기존 파일 설명자로 복사됩니다 dup2(). 이는 쉘에서 사용하는 메커니즘과 정확히 동일하지만 리디렉션 기호 의 >용어 유형에 관한 한 이는 여전히 쉘 제어 하에 있으므로 상위 쉘에 의해서만 해석될 수 있습니다.

왜 2>/dev/null인가요?

일반적으로 진단 출력이 로 전송되는 것으로 알려져 있습니다 stderr. 실제로 해당 주제에 대한 두 가지 훌륭한 기사가 이미 있습니다.

watch귀하의 예 에서 규칙을 따르십시오 strace. 그게 전부입니다. 2>/dev/null그러한 명령의 출력을 숨기도록 지정하는 요구 사항 자체는 없습니다 .

예를 들어 인수로 전달된 명령에 대한 리디렉션을 실제로 지정하려면 strace해당 명령 주위에 셸이 있어야 합니다. 예를 들어,

strace -f bash -c 'stat /etc/passwd nonexisting 2>/dev/null'

플래그 사용 시 주의하세요 -f. 명령에 적용된 시스템 호출을 추적하는 데 초점을 맞추는 경우 stat플래그 없이는 해당 호출을 볼 수 없기 때문입니다 -f.

관련 정보