This is just a demonstration to illustrate the use of the USR1
signal with dd
.
dd if=/dev/zero of=/dev/null &
starts dd
in the background, copying data from /dev/zero
(which produces zeroes whenever a program reads from it) to /dev/null
(which discards anything written to it). This provides a harmless instance of dd
which can be used to experiment with — it doesn't use up any storage, and will keep on running as long as we want it to, which gives the user time to send signals to it.
pid=$!
stores the process identifier of the last background command ($!
) in the variable pid
.
kill -USR1 $pid
sends the USR1
signal to the process whose identifier is the value stored in the pid
variable, the background dd
in this case. When dd
receives this signal, it prints out its current progress (the amount of data read and written) and continues copying.
sleep 1
waits one second.
kill $pid
sends the TERM
signal to dd
, which causes dd
to exit. (There's no point in leaving the background dd
running here.)
It would be more instructive to run this instead of the second line above:
kill -USR1 $pid; sleep 1; kill -USR1 $pid; kill $pid
This would output the progress twice, with one second in between, to show dd
's progress; then kill dd
without waiting.
For actual use, you'd specify appropriate inputs and outputs for the original dd
command, and probably some other options too, and you wouldn't run the last kill
— you'd wait for dd
to finish of its own accord.
To answer your final question, this is how you send USR1
signals from a shell (or any other signal): you use kill
with the signal you want to send, and the process identifiers (or job identifiers) of the processes you want to send the signal to. Other (non-POSIX) commands you can use are pkill
and killall
, when you want to find processes by name.