추가 터미널?

추가 터미널?

저는 리눅스를 배우고 있어요. 프로세스를 터미널에 붙일 수 있다는 아이디어가 떠올랐습니다. 터미널(TTY)에 프로세스를 연결한다는 것은 무엇을 의미합니까? 왜 이 일을 해야 합니까?

답변1

노트: Unix의 작업 제어를 더 잘 이해하기 위해 해당 주제에 대한 Wikipedia 페이지로 안내하겠습니다.작업 제어(Unix).


추가 터미널?

"터미널에 연결"이라는 문구는 일반적으로 쉘 컨텍스트에서 작업에 대해 말할 때 듣는 것입니다. 그러나 그것은 다른 의미도 가지고 있습니다. "터미널에 프로세스 연결"이라는 문구는 또는 gdb특정 프로세스 ID(PID)에 연결하고 정보를 나열하거나 모니터링하는 것과 같은 strace도구를 사용하는 것을 의미할 수도 있습니다.lsof

이 두 가지에 대해 모두 논의할 예정이지만 먼저 작업 대기열에 대해 논의하겠습니다. 왜냐하면 그것이 여러분이 찾고 있는 대기열이라고 생각하기 때문입니다.

배경 - 작업 대기열

Unix 계열 운영 체제에서는 일반적으로 작업이라는 개념을 볼 수 있습니다. 일반적으로 내가 사용한 대부분의 Unix 계열 운영 체제에서 비슷한 방식으로 작동합니다. 즉, 백그라운드에서 실행될 수 있고 대기열(작업 대기열)에 번호가 할당될 수 있으며 해당 작업 대기열에 있는 번호의 컨텍스트에 따라 작동될 수 있습니다.

작업 대기열에 무언가를 넣기 위해 종종 이 동작을 백그라운드 처리라고 부릅니다. 이미 백그라운드에서 실행 중인 작업을 재개하는 경우 이를 포그라운드 처리라고 합니다. 이를 수행하는 일반적인 명령 bg은 입니다 fg. &실행하는 명령 끝에 "&" 기호를 사용하여 작업을 백그라운드로 즉시 전환 할 수도 있습니다 .

일하다

$ sleep 2 &
[1] 19189

여기서는 sleep 명령을 2초 동안 실행하고 백그라운드에 넣어두었습니다. 출력에서는 작업 대기열 번호( [1]) 및 백그라운드 작업의 프로세스 ID 19189와 같은 유용한 정보를 즉시 제공합니다.

이 작업이 최종적으로 종료되면 실행 중인 터미널에 다음과 같은 메시지가 인쇄됩니다.

$
[1]+  Done                    sleep 2

전경과 배경

백그라운드 작업에 대한 작업을 수행하려면 다음을 수행하십시오.

$ sleep 20 &
[1] 19207

$ fg
sleep 20
^C

여기서는 작업을 백그라운드( &)로 보낸 다음 다시 포그라운드( )로 가져온 fg다음 Ctrl+ C( ^C) 명령을 사용하여 작업을 종료합니다.

백그라운드 작업이 여러 개인 경우:

$ sleep 20 &
[1] 19224
$ sleep 20 &
[2] 19225
$ sleep 20 &
[3] 19226
$ jobs
[1]   Running                 sleep 20 &
[2]-  Running                 sleep 20 &
[3]+  Running                 sleep 20 &

우리는 명령을 사용하여 그것들을 볼 수 있습니다 jobs. #3 과 #2 옆에 있는 작은 합계를 확인하세요 +. 작업 대기열 번호를 지정하지 않고 명령 -을 실행하면 fg마지막 작업이 작업 대기열( )에 추가됩니다 +. 예를 들어:

$ fg
sleep 20
^C

$ jobs
[1]-  Running                 sleep 20 &
[2]+  Running                 sleep 20 &

죽이다

작업 대기열 번호를 사용하여 작업을 처리할 수 있습니다. 한 가지 방법은 그들을 죽이는 것입니다. 작업 대기열 번호를 참조하려면 %다른 명령과 함께 참조하려는 경우 해당 번호 앞에 접두사를 붙일 수 있습니다 kill. 물론, kill한 번에 둘 이상을 사용할 수도 있고 하나만 사용할 수도 있습니다.

$ kill %3 %4 %5
$ jobs
[3]   Terminated              sleep 20
[4]   Terminated              sleep 20
[5]-  Terminated              sleep 20
[6]+  Running                 sleep 20 &

PID에 연결된 배경

프로세스를 터미널에 연결한다는 것은 다음을 의미할 수도 있습니다. 이것은 내 쉘의 PID입니다.

$ echo $$
23543

다른 셸에서는 strace프로세스를 실행하고 연결하여 어떤 시스템 호출이 수행되고 있는지 확인합니다.

$ strace -p 23543
strace: Process 23543 attached
read(0,

노트:read여기에서 for 명령을 기다리고 있는 것을 볼 수 있습니다 . 이것이 터미널/셸의 용도입니다.

여기서 우리는 명령을 입력하기 시작했고 ls쉘이 이것을 시스템 호출의 형태로 쉘에 다시 에코하는 것을 볼 수 있습니다 write().

read(0, "l", 1)                         = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "l", 1)                        = 1
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
read(0, "s", 1)                         = 1
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0
write(2, "s", 1)                        = 1
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
read(0,

이는 터미널에 프로세스를 연결하는 또 다른 형태입니다.

다른 형태

프로세스를 터미널에 연결하는 것에 대한 보다 모호한 참조 중 하나를 여기서도 가정할 수 있습니다. 이 U&L Q&A의 질문은 다음과 같습니다.분리된 프로세스에 터미널을 연결하는 방법은 무엇입니까?이 콘텐츠의 모든 형태가 포함됩니다.

이 형식의 인용의 기본 전제는 백그라운드 작업을 완료하고 현재 셸에서 해당 작업을 "연결 해제"했다는 것입니다. 또는 명령을 사용하여 nohup이를 수행 할 수 있습니다 disown.

프로세스가 거부되면 더 이상 jobs, fg또는 bg명령을 사용하여 작업을 수행할 수 없습니다. 더 이상 현재 쉘의 PID와 연결되지 않습니다.

reptyr이전에 거부된 프로세스를 다시 획득하는 전통적인 방법 은 PID를 기존 셸에 다시 연결하는 것과 같은 도구를 사용하는 것입니다 . 예를 들어, 우리가 2개의 작업을 시작했고 그 작업이 다음과 같다고 가정해 보겠습니다 nohup.

$ nohup sleep 200 &
[1] 19720
$ nohup sleep 200 &
[2] 19721

여전히 터미널의 작업 대기열에 연결되어 있습니다 disown. 다음을 수행해 보겠습니다.

$ jobs
[1]-  Running                 nohup sleep 200 &
[2]+  Running                 nohup sleep 200 &
$ disown -a

이제 그들은 사라졌습니다:

$ jobs
$

이들은 여전히 ​​원래 셸 PID(23543)의 하위 항목으로 나열됩니다.

$ ps -eaf|grep -E "19720|19721"
vagrant  19720 23543  0 18:29 pts/1    00:00:00 sleep 200
vagrant  19721 23543  0 18:29 pts/1    00:00:00 sleep 200

이제 로그아웃했다가 다시 로그인하면 이러한 프로세스가 이제 기본 PID 1의 상위로 나열되는 것을 볼 수 있습니다.

$ ps -eaf|grep -E "19720|19721"
vagrant  19720     1  0 18:29 ?        00:00:00 sleep 200
vagrant  19721     1  0 18:29 ?        00:00:00 sleep 200

nohup이러한 프로세스는 우리가 편집하고 편집하기 때문에 이를 수행할 수 있습니다 disown. 그 중 하나를 다시 연결해 보겠습니다.

$ reptyr -s 19720
[-] Timed out waiting for child stop.

^C

노트:위에서는 PID 19720을 쉘에 다시 연결한 다음 Ctrl+ 를 통해 종료합니다 C. 이제 사라진 것을 볼 수 있습니다.

$ ps -eaf|grep -E "19720|19721"
vagrant  19721     1  0 18:29 ?        00:00:00 sleep 200

관련 정보