모든 프로그램(예: dd)에 대해 명령줄에서 신호를 사용/보내는 방법

모든 프로그램(예: dd)에 대해 명령줄에서 신호를 사용/보내는 방법

dd나는 다음과 같은 프로그램 의 맨페이지를 이해하려고 노력하고 있습니다 .

실행 중인 'dd' 프로세스에 USR1 신호를 보내면 I/O 통계를 표준 오류로 인쇄한 다음 복사를 다시 시작합니다.

         $ dd if=/dev/zero of=/dev/null& pid=$!
         $ kill -USR1 $pid; sleep 1; kill $pid

무슨 pid=$!뜻인가요?

이것은 pid를 얻는 변수의 할당입니까 dd? 그리고 결국 변수에 사용됩니까 $pid?

또한 왜 사용 sleep합니까 kill?

이런 사용방법인가요 -USR1?

답변1

dd if=/dev/zero of=/dev/null&

후행은 &백그라운드에서 prefix 명령을 실행하는 것을 의미합니다. (면책조항: 이는 지나치게 단순화된 진술입니다)

인용하다이것:

$! 가장 최근 백그라운드 명령의 PID입니다.

그래서 pid=$!할당가장 최근의 배경 PIDPID 인 변수 pid에 dd.

또한 그들은 왜 잠을 자고 죽이는가?.

당신은 필요kill $pid (매개변수를 지정하지 않은 경우 종료에 대한 기본 신호는 프로세스 종료를 의미하는 TERM입니다.)dd테스트를 마친 후 프로세스를 종료 하지 않으면 dd프로세스가 백그라운드에 머물면서 CPU 리소스를 소모할 수 있습니다. 확인하려면 플랫폼의 시스템 모니터를 확인하세요.

I/O 통계를 인쇄하는 반면 Kill -USR1 $pid프로세스를 종료하지 않습니다.

1초 동안 대기하지 않으면 프로세스는 터미널에 통계 출력을 쓰기 전에 dd마지막 명령문에 의해 종료될 수 있습니다 **. kill $pid프로세스는 동기식이지만트랩+쓰기 작업( kill -USR1 $pid)는 다음보다 느릴 수 있습니다.작업 종료( kill $pid). 따라서 두 번째로 통계 출력이 인쇄 완료되었는지 확인하기 위해 sleep 1시작을 지연합니다 .kill $pid

-USR1을 사용하는 방법은 무엇입니까?

단지 man dd:

실행 중인 'dd' 프로세스에 USR1 신호를 보내면 I/O 통계를 표준 오류로 인쇄한 다음 복사를 다시 시작합니다.

그리고 man 7 signal:

   SIGUSR1   30,10,16    Term    User-defined signal 1
   SIGUSR2   31,12,17    Term    User-defined signal 2

두 진술을 결합하면 USR1이 다음과 같다는 것을 이해해야 합니다.사용자 정의 신호dd사용자가 중단할 수 있는 방법을 제공하기 위해 정의됩니다 .I/O 통계 인쇄즉석에서. 이는 프로그램별 처리기이므로 통계 출력을 기대할 수 있다는 의미는 아닙니다 kill -USR1 other_program_pid.

또한 당신은 관심을 가질 수 있습니다이: SIGUSR1이 프로세스를 종료시키는 이유는 무엇입니까?.

답변2

USR1이것은 신호 의 사용을 설명하기 위한 데모일 뿐입니다 dd.

dd if=/dev/zero of=/dev/null &

dd백그라운드에서 시작하여 /dev/zero(프로그램이 읽을 때마다 0이 생성됨) 에서 /dev/null(기록된 모든 내용이 삭제됨)로 데이터를 복사합니다. 이는 실험에 사용할 수 있는 무해한 인스턴스를 제공합니다 dd. 이는 스토리지를 사용하지 않고 우리가 원하는 동안 계속 실행되므로 사용자가 신호를 보낼 시간을 제공합니다.

pid=$!

마지막 백그라운드 명령( )의 프로세스 식별자를 $!변수에 저장합니다 pid.

kill -USR1 $pid

USR1식별자가 변수에 저장된 값인 프로세스( 이 경우 pid배경) 에 신호를 보냅니다 . 이 신호를 dd받으면 dd현재 진행 상황(읽고 쓴 데이터의 양)을 인쇄하고 계속 복사합니다.

sleep 1

1초만 기다립니다.

kill $pid

TERM에 신호를 보내면 종료됩니다 dd. ( 여기서 dd배경을 계속 실행하는 것은 의미가 없습니다 .)dd

위의 두 번째 줄 대신 이것을 실행하는 것이 더 유익할 것입니다.

kill -USR1 $pid; sleep 1; kill -USR1 $pid; kill $pid

dd이는 의 진행 상황을 표시하기 위해 1초 간격으로 진행 상황을 두 번 출력합니다 . 그런 다음 dd기다리지 않고 죽여라 .

실제 사용을 위해 원래 명령에 대한 적절한 입력 및 출력과 다른 옵션도 지정하고 dd마지막 명령을 실행하지 않고 자체적으로 완료될 때 kill까지 기다립니다 .dd

USR1마지막 질문에 답하기 위해 쉘(또는 다른 신호)에서 신호를 보내는 방법은 다음과 같습니다 .kill보내려는 신호와 신호를 보내려는 프로세스의 프로세스 식별자(또는 작업 식별자)를 포함합니다. 사용할 수 있는 기타(POSIX가 아닌) 명령은 다음과 같습니다.pkill그리고killall, 이름으로 프로세스를 찾으려는 경우.

답변3

대부분 또는 모든 셸의 경우 $!셸이 분기한 마지막 프로세스의 프로세스 ID(PID라고도 함)입니다. 명령 dd은 로 분기되었으므로 분기 직후 &프로세스 ID가 쉘 변수에 할당됩니다 .pid=$!ddddpid

프로세스 ID는 Linux 또는 Unix에서 일부 코드가 실행되는 주소 공간을 참조하는 데 사용되는 숫자입니다.

프로그램 kill의 목적은 프로세스에 신호(작은 비동기 메시지)를 보내는 것이기 때문에 이름이 직관적이지 않습니다. 신호는 몇 개(총 128개)뿐이며 숫자와 이름이 모두 있습니다. 예를 들어 "kill" 신호는 9번입니다. USR1은 번호 10으로 정의됩니다. 따라서 kill -USR1 $pid번호 10인 프로세스에 신호 10을 보냅니다 $pid. 때로는 실행하는 데 시간이 오래 걸리므로 이전에 분기되어 백그라운드에서 실행된 명령 dd의 프로세스 ID인 것이 거의 확실합니다 . ddkill $pid명령은 동일한 프로세스 ID에 TERM 신호를 보냅니다. TERM은 "종료"를 의미합니다. 잘 작성된 프로그램은 일반적으로 TERM을 포착하고 할당한 리소스를 정리한 다음 종료됩니다.

dd왜 백그라운드에서 실행하고 USR1 신호를 보내고 1초 동안 기다린 다음 dd모든 리소스를 할당 해제하고 종료하는지 완전히 확신할 수 없습니다. 전체 코드 조각은 dd오랜 시간 동안 실행된다고 가정하는 것으로 보이지만 이는 사실이 아닐 수도 있습니다. 내 생각에 이 코드에는 경쟁 조건이 있으며 원하는 의미가 무엇이든 실제로 얻지 못할 수도 있습니다.

답변4

dd명령이 포그라운드에서 실행되고 현재 진행 상태를 표시할 것으로 예상되는 경우 . 플래그를 사용하여 명령을 실행해 보세요 status=progress.

sudo dd if=/dev/sda of=/dev/sdb status=progress

그러면 진행 상황이 동적으로 표시됩니다.

dd이는 GNU 구현 (2015년에 출시된 버전 8.24에 추가됨) 의 확장 으로, dd12.0(2018) 이후 FreeBSD 구현에서도 사용할 수 있지만 일반적으로 다른 BSD를 포함한 다른 구현에서는 사용할 수 없습니다.

관련 정보