왜 일부 명령이 완료 될 때까지 터미널을 '매달려'합니까?


22

때로는 터미널에서 프로그램을 실행합니다 (예 : lxpanel†) . 터미널이 프롬프트로 다시 돌아 가지 않고 중단됩니다. Ctrl+ C를 누르면 프롬프트로 돌아갈 수 있지만이 경우 종료됩니다 lxpanel. 그러나 Alt+ F2(명령을 표시하는 창이 팝업 됨)를 누르고 실행하면 lxpanel정상적으로 작동합니다.

왜 이런거야? 터미널에서 명령을 실행하는 것과 Alt+ 를 누를 때 나타나는 '실행'창과 다른 점은 무엇입니까 F2?

여기서 lxpanel은 예제로 사용되었습니다. 여러 프로그램에서 이것을 경험했습니다.


1
팁 : GNU Screen ( screen)을 사용하면 더 오래 실행되는 프로세스를 "랩핑"할 수 있습니다. 쉘에서 분리하여 쉘로 돌아간 다음 다시 연결하여 실행중인 프로세스의 출력을 볼 수 있습니다. 재 연결은 다른 터미널, SSH 등에서도 수행 할 수 있습니다. 이러한 종류의 작업을 수행 할 수있는 다른 프로그램도있을 수 있습니다.
poplitea

답변:


28

기본적으로 터미널은 포 그라운드에서 프로그램을 실행하므로 프로그램이 완료 될 때까지 쉘에서 다시 종료되지 않습니다. 이것은 stdin에서 읽거나 stdout에 쓰는 프로그램에 유용합니다. 일반적으로 많은 프로그램이 한 번에 실행되는 것을 원하지 않습니다. 백그라운드에서 프로그램을 실행하려면 다음과 같이 시작할 수 있습니다.

$ lxpanel &

또는 이미 실행중인 경우 Ctrl+로 일시 중단 Z한 다음 실행 bg하여 백그라운드로 이동할 수 있습니다. 어느 쪽이든 새 쉘 프롬프트로 끝나지만 프로그램은 여전히 ​​실행 중이며 출력은 터미널에 나타납니다 (따라서 입력하는 동안 갑자기 나타날 수 있습니다)

일부 프로그램 (일반적으로 데몬)은 시작할 때 별도의 프로세스를 분기 한 다음 기본 프로세스를 즉시 종료합니다. 이를 통해 쉘을 차단하지 않고 프로그램을 계속 실행할 수 있습니다.


Alt + f2를 눌러 '실행'창을 통해 프로그램을 실행할 때 실제로 시스템이 수행하는 작업은 무엇입니까? (적어도 gnome과 openbox에서는 alt + f2가 그렇게합니다). 명령을 입력하자마자 프로그램이 시작되고 상자가 사라지기 때문에 묻습니다. 그냥 &를 추가합니까?
sqram

2
@lyrae : 기본적으로 쉘은 쉘 세션을 계속하기 전에 프로그램이 완료되기를 기다립니다. "hang"의 정의에 의해 "hang"되지 않습니다. Alt + F2는 프로그램을 기다리지 않습니다. 쉘이 프로그램이 완료되기를 기다리는 이유는 쉘이 사용자가 쉘에 입력 한 모든 것을 프로그램의 표준 입력 및 / 또는 디스플레이 프로그램의 표준 출력으로 경로 재 지정할 수 있기 때문입니다. alt + f2는 주로 GUI 프로그램을 시작하는 데 사용되므로 alt + f2는 표준 입력 / 출력을 사용할 가능성을 제공하지 않으므로 기다릴 필요가 없습니다.
Lie Ryan

1
@lyrae : alt + f2는 백그라운드에서 프로그램을 시작하기 위해 특별한 작업을 수행하지 않습니다. '&'를 추가하는 것은 쉘의 기능입니다. '&' 없이 명령 시작할 때 , 쉘은 프로그램의 표준 입력을 자신의 표준 입력으로 리디렉션하고 프로그램의 표준 출력을 자신의 표준 출력으로 리디렉션합니다 (쉘은 Ctrl 인터셉트와 같은 다른 많은 서비스도 제공하기 때문에 약간 생각합니다) -C, SIGINT 신호 명령을 포 그라운드 프로그램으로 전송). '&'는 쉘에게 그렇게하지 말고 프로그램을 시작하도록 지시한다.
Lie Ryan

1
@LieRyan 쉘이하는 말 중 일부는 실제로 커널의 터미널 드라이버에 의해 처리되며, "with &"는 쉘이 wait ()를 호출하는 것 이외의 "with &"보다 일반적으로 "특별"합니다. waitpid 또는 동급]] alt-f2에 의해 수행되지 않습니다.
Random832

6

터미널에서 프로그램을 시작하면 프로그램이 중지 될 때까지 터미널이 "중지"됩니다. Ctrl+ c를 누르면 프로그램이 닫히므로 프롬프트로 돌아갑니다. 예를 들어 모든 GUI 응용 프로그램에서이를 볼 수 있습니다. 예를 들어 Firefox를 사용해보십시오.

Alt + F2와 같은 다른 방법을 사용하거나 메뉴를 클릭하면 프로그램이 백그라운드에서 시작되므로 이상한 일이 발생하지 않으며 명령 프롬프트가 없습니다.

터미널에서 GUI 앱을 계속 실행 &하려면 명령 끝에 다음과 같이 추가 하십시오.

lxpanel &

그러면 터미널 lxpanel이 백그라운드에서 실행 되고 즉시 다른 프롬프트가 표시됩니다.


3

프로그램은 기본적으로 해당 쉘의 포 그라운드에서 실행되는 쉘을 통해 실행됩니다. 이로 인해 쉘은 작업을 중단하고 stdin / stdout / sterr를 터미널에서 프로그램으로 보냅니다. 데스크탑 환경을 통해 실행되는 프로그램은 분기 되어 실행 된 프로그램과 독립적으로 실행됩니다. 이것은 &명령에 a 를 추가하여 대부분의 쉘에서 시뮬레이트 할 수 있지만, 여전히 std *를 터미널에 연결합니다 (백그라운드 프로그램의 stdin에서 읽는 경우 더 복잡함).


2

나중에 콘솔 상호 작용을 필요로하는 프로그램 (예 : "apt -y update &")을 제외하고 사용자에게 "정말 힘을 내야합니까?" .... 아무도 더 이상보고 있지 않을 때).

이 구멍을 막고 프로세스가 터미널을 절대 사용할 수 없게하는 과정을 알리기 위해 <&-를 일부 명령에 추가하여 활성 터미널에서 완전히 분리하여 STDIN이 더 이상 불가능하다는 것을 알려줍니다. 그래도 사용한다면 / bin / bash가 쉘인지 확인하십시오. 스크립트는 프롬프트를 캐스트 할 의사 터미널이없는 것과 관련된 오류를 로깅합니다.

예를 들면 다음과 같습니다.

`./runme.sh &> runme.log <&- & disown`

현재 터미널 세션에서 연결을 끊는 최고의 방법입니다. STDOUT과 STDERR 모두 runme.log에 기록됩니다. 콘솔이나 셸이 더 빨리 종료되는지 또는 다른 계정으로 로그 아웃 / 실행 한 경우 (runme에서 터미널 가비지가 발생하지 않음), 부모 자식까지도 제거 할 수 없기 때문에 중요하지 않습니다. PID 관계가 제거되었습니다.

업데이트 : 그럼에도 불구하고 세마포어를 원래 부모의 이름과 연결하는 데 문제가 있었으므로 이제 대신 권장합니다.

at now <<< "(cmd1; cmd2; etc.) &> logfile.log"

물론 CRON에서 출력을 이메일로 받으려면 &>를 제거하거나 파일 대신 / dev / null로 리디렉션하십시오.


내가 사용하기 시작한 약간 덜 복잡한 방법은 다음과 같습니다.at now <<< "(cmd1; cmd2; etc.) &> logfile.log"
Marcos
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.