쉘 exec내장(첫 번째 뉘앙스)

쉘 exec내장(첫 번째 뉘앙스)

프로그램(Steam)의 모든 출력을 /dev/null로 리디렉션하여 터미널에 표시되지 않게 하려고 합니다.

내가 시도한 것은 다음 steam & > /dev/null 2>/dev/null과 같습니다.steam & > /dev/null 2>&1

어느 쪽도 메시지를 억제하지 않습니다(내가 알 수 있는 한).

내 이해는 터미널에서 프로세스를 분리하고 > 기본/공백이 stdout이고 2>가 stderr인 상태에서 입력/출력을 리디렉션한다는 것입니다. 그 둘보다 더 많은 출력이 있습니까? 모든 출력을 리디렉션하는데도 출력이 계속 표시되는 이유는 무엇입니까?

답변1

노력하다:

steam 2>&1 > /dev/null &

2>&1stderr를 stdout으로 리디렉션하고 > /dev/nullstdout을 /dev/null.

&프로세스를 배경으로 하는 위치가 잘못되었습니다 . 줄의 끝 부분에 가야 합니다. 뒤에 배치 steam하고 앞에 배치하면 프로세스가 적절하게 백그라운드로 진행되더라도 >에서 아무것도 리디렉션되지 않습니다.steam

답변2

이 특별한 문제는 steam때때로 특별한 이해와 처리가 필요할 수 있는 특별한 경우입니다. 런타임 steam은 다음을 포함하는 래퍼 스크립트입니다.

#!/bin/bash
# default to minimize on close, so we never have a running steam process
# in the background because of a broken Tray Icon on some desktops/WMs
#export STEAM_FRAME_FORCE_CLOSE=${STEAM_FRAME_FORCE_CLOSE:-0}
exec /usr/lib/steam/steam "$@"

exec내장된 쉘을 사용 하고 $@.

따라서 쉘 출력 리디렉션에 대한 일반적인 솔루션은 다음과 유사합니다.@Adobe 및 @Gary의 답변, 이러한 특정 유형의 사례에는 좀 더 미묘한 접근 방식과 뒤에서 무슨 일이 일어나고 있는지에 대한 이해가 필요할 수 있습니다. 가능한 모든 출력 리디렉션 방법과 작업 순서가 steam때때로 예상대로 작동하지 않는 이유에 대해서는 약간의 미묘함이 있습니다 .

exec내장(첫 번째 뉘앙스)

POSIX 표준은 다음에 대한 동작을 정의합니다.명령exec. Bash는 이를 다음을 통해 제공합니다.exec쉘 내장. 호출 방법에 따라 표준 IO 리디렉션 및 하위 프로세스 트리에 영향을 미칠 수 있습니다. 메모:이는 OP의 특정 사용 사례 및 나열된 명령에 기술적으로 적용되지 않았지만, 주의해야 할 일반적인 함정과 주의 사항이기 때문에 여기에 포함시켰습니다.

IEEE Std. 1003.1, 2004년판:

exec 유틸리티는 명령의 일부로 리디렉션에 지정된 대로 파일 설명자를 열고, 닫고, 복사해야 합니다.

exec가 명령이나 인수 없이 지정되고 2보다 큰 숫자를 가진 파일 설명자가 관련 리디렉션 문과 함께 열리는 경우, 쉘이 다른 유틸리티를 호출할 때 해당 파일 설명자가 열려 있는지 여부는 지정되지 않습니다. 하위 셸이 열린 파일 설명자를 오용할 수 있다는 점을 우려하는 스크립트는 다음 예 중 하나에 표시된 것처럼 항상 명시적으로 닫을 수 있습니다.

exec가 command와 함께 지정되면 새 프로세스를 생성하지 않고 쉘을 command로 대체합니다. 인수가 지정되면 명령에 대한 인수가 됩니다. 리디렉션은 현재 쉘 실행 환경에 영향을 미칩니다.

exec /usr/lib/steam/steam "$@"래퍼 스크립트 의 줄은 새로운 하위 프로세스를 생성하지 않고 /usr/bin/steam실행 중인 셸("shebang 줄에 따라)을 대체합니다 . 인수 지정자는 큰따옴표로 전달되며, 이는 대부분의 경우 IO 리디렉션 연산자로 인한 부작용을 방지해야 합니다. 그러나 일부 출력 리디렉션 연산자를 인수로 전달하면(예: 잘못된 따옴표 또는 escape char 사용 ) 호출이 표준에 영향을 미칠 수 있도록 쉘 리디렉션 연산자를 스크립트에 삽입할 수 있다는 점을 알아두는 것이 좋습니다. 명령의 IO 및 파일 설명자. 또는 기타 리디렉션 연산자를 래퍼 스크립트에 전달하는 방법에 따라 다음 과 같은 맥락에서 평가됩니다 . 다행히 이 경우 큰따옴표는 대부분의 부작용을 제거합니다. 하지만 어떤 bash 프로세스나 하위 쉘이 해당 인수를 평가하는지 주의하는 것이 중요합니다./bin/bash$@"'eval\exec2>&1>somefile"$@"

Unix 출력 리디렉션: stdin, stdout, &stderr

대부분의 유닉스REPL쉘에는 리디렉션을 위한 유사한 방법이 있습니다.표준 IO 스트림, stdin, stdout, 그리고 stderr. 여기에는 POSIX sh, Bash, Z Shell zsh, Korn Shell ksh, C Shell csh, Dash dash등이 포함되지만 이에 국한되지는 않습니다 .

OP 질문의 목적에 따라 /usr/bin/steam래퍼 스크립트는 Bash로 시작하므로 Bash에만 중점을 둘 것입니다.오두막" 선: #!/bin/bash.

Bash에서 처음 3개의 파일 설명자( fd')는 항상 다음과 같이 정의되며 0부터 시작하여 색인이 지정됩니다 0.

  • stdin=fd 0
  • stdout=fd 1
  • stderr=fd 2

모든 명령의 출력은 다음을 사용하여 리디렉션될 수 있습니다.Bash의 출력 리디렉션 연산자(Bash 참조 매뉴얼: § 3.6 리디렉션). 이에 대한 기본 소개는 다음 문서에서 확인할 수 있습니다.설명자를 사용한 재미있는 Bash 리디렉션. 좀 더 직관적인 설명을 위해 시각적 자료를 활용하여이 훌륭한 기사를 참조하십시오 (추천!).

작업 순서(두 번째 뉘앙스):

다음 사이에는 미묘한 작업 순서가 있습니다.

... 그리고:

로부터Bash 참조 매뉴얼 § 3.6 리디렉션:

리디렉션은 나타나는 순서대로 왼쪽에서 오른쪽으로 처리됩니다.

[...한조각...]

리디렉션 순서가 중요합니다. 예를 들어 다음 명령은

ls > dirlist 2>&1

표준 출력(파일 설명자 1)과 표준 오류(파일 설명자 2)를 모두 파일 디렉토리 목록으로 보내는 반면, 명령은

ls 2>&1 > dirlist

표준 출력이 dirlist로 리디렉션되기 전에 표준 오류가 표준 출력의 복사본으로 만들어졌기 때문에 표준 출력만 파일 dirlist로 보냅니다.

&마찬가지로 및 기타 제어 연산자 에도 작업 순서가 있습니다 .

로부터Bash 참조 매뉴얼: 2.4 명령 목록:

목록은 연산자 ' ;', ' &', ' &&' 또는 ' ' 중 하나로 구분되고 선택적으로 ' ', ' ' 또는 a ||중 하나로 끝나는 하나 이상의 파이프라인 시퀀스입니다 .;&newline

이러한 목록 연산자 중 ' &&'과 ' ||'는 동일한 우선순위를 가지며, 그 다음에는 동일한 우선순위를 갖는 ' ;' 및 ' '가 옵니다.&

명령을 구분하기 위해 하나 이상의 줄 바꿈 시퀀스가 list​​세미콜론과 동일하게 나타날 수 있습니다.

마지막으로 구체적으로 다음 섹션에 대해 설명합니다 &.

명령이 제어 연산자 ' &'에 의해 종료되면 쉘은 서브쉘에서 명령을 비동기적으로 실행합니다. 이는 다음에서 명령을 실행하는 것으로 알려져 있습니다.배경, 이를 다음과 같이 지칭합니다.비동기식명령. 쉘은 명령이 완료될 때까지 기다리지 않으며 반환 상태는 0( true)입니다. 작업 제어가 활성화되지 않은 경우(참조:작업 제어), 명시적인 리디렉션이 없는 경우 비동기 명령에 대한 표준 입력은 에서 리디렉션됩니다 /dev/null.

OP의 명령이 예상한 대로 수행되지 않은 이유

시도한 처음 두 명령은 다음과 같습니다.

  • steam & > /dev/null 2>/dev/null
  • steam & > /dev/null 2>&1

stdout이들이 예상한 대로 두 가지 모두의 의도된 리디렉션을 수행하지 못한 이유 stderr는 앞서 언급한 사항 때문입니다.연산 순서/연산자 우선순위위에 나열된 규칙. 특히 &연산자는 왼쪽에서 오른쪽 순서로 먼저 표시됩니다. 첫 번째 단어인 명령에 적용되어 다음 steam과 같이 실행되는 배경으로 보냅니다.비동기 명령. stdin에 연결되어 있는 /dev/null반면 stdoutstderr제어 장치에 연결되어 있습니다.의사 터미널 /pty. 이에 대해서는 아래에서 자세히 설명합니다.

하지만 먼저...

더 많은 연쇄 exec혼란!

관련 정보