나는 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
(매개변수가 지정되지 않은 경우 kill의 기본 신호는 TERM이며 이는 프로세스가 종료됨을 의미합니다.)dd
테스트를 완료한 후 프로세스를 종료하십시오. 그렇지 않으면 dd
프로세스가 백그라운드에 남아 CPU 리소스를 소모할 수 있습니다. 플랫폼의 시스템 모니터를 확인하여 확인하세요.
I/O 통계가 인쇄 되지만 Kill -USR1 $pid
프로세스가 종료되지는 않습니다.
dd
1초 동안 대기하지 않으면 프로세스가 터미널에 통계 출력을 쓰기 전에 마지막 명령문에 의해 프로세스가 종료될 수 있습니다 . 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
백그라운드에서 시작하여 데이터는 (프로그램이 읽을 때마다 0을 생성함)에서 (기록된 내용을 모두 삭제) /dev/zero
로 복사 됩니다. /dev/null
이는 dd
실험에 사용할 수 있는 무해한 인스턴스를 제공합니다. 이는 저장 공간을 차지하지 않고 원하는 만큼 계속 실행될 수 있으므로 사용자가 신호를 보낼 시간을 제공합니다.
pid=$!
마지막 백그라운드 명령의 프로세스 식별자를 $!
변수에 저장합니다 pid
.
kill -USR1 $pid
식별자가 변수(이 경우 배경) USR1
에 저장된 값인 프로세스에 신호를 보냅니다 . 이 신호를 받으면 현재 진행 상황(읽고 쓴 데이터의 양)을 인쇄하고 계속 복사합니다.pid
dd
dd
sleep 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=$!
dd
dd
pid
프로세스 ID는 Linux 또는 Unix에서 일부 코드가 실행되는 주소 공간을 참조하는 데 사용되는 숫자입니다.
프로그램 kill
이름은 그 목적이 프로세스에 신호(작은 비동기 메시지)를 보내는 것이기 때문에 직관적이지 않습니다. 약 128개의 신호만 있으며 모두 번호와 이름이 지정되어 있습니다. 예를 들어, "kill" 신호는 숫자 9입니다. USR1은 숫자 10으로 정의됩니다. 따라서 kill -USR1 $pid
신호 10이 프로세스 번호 로 전송됩니다 $pid
. dd
때로는 실행하는 데 오랜 시간이 걸리므로 이는 dd
이전에 분기되어 백그라운드에서 실행된 명령의 프로세스 ID인 것이 거의 확실합니다. 이 kill $pid
명령은 동일한 프로세스 ID에 TERM 신호를 보냅니다. TERM은 "종료"를 의미합니다. 잘 작성된 프로그램은 일반적으로 TERM을 포착하고 할당된 리소스를 정리한 다음 종료됩니다.
dd
왜 백그라운드에서 실행하고 USR1 신호를 보내고 1초 동안 기다린 다음 dd
모든 리소스를 해제하고 종료하는지 잘 모르겠습니다 . 전체 코드 조각에서는 dd
실행하는 데 오랜 시간이 걸린다고 가정하는 것 같지만 사실이 아닐 수도 있습니다. 내 생각에 이 코드에는 경쟁 조건이 있으며 원하는 의미가 무엇이든 실제로 얻지 못할 수도 있습니다.
답변4
dd
명령을 포그라운드에서 실행하고 현재 진행 상태를 표시하려는 경우 . status=progress
플래그를 사용하여 명령을 실행 해 보세요 .
sudo dd if=/dev/sda of=/dev/sdb status=progress
그러면 진행 상황이 동적으로 표시됩니다.
이는 12.0(2018) 이후 FreeBSD에서의 구현에도 사용할 수 있는 GNU 구현 dd
(2015년에 출시된 버전 8.24에 추가됨) 에 대한 확장이지만 일반적으로 다른 BSD에서의 다른 구현은 제외됩니다.dd