Linux dd实用程序未准备好接收终止信号
我有一个脚本,可以解压缩Linux dd实用程序未准备好接收终止信号,linux,bash,shell,dd,Linux,Bash,Shell,Dd,我有一个脚本,可以解压缩.gz文件并将其复制到块设备中。我使用dd获取有关进度的信息(我不能使用其他实用程序,如pv来实现这一点)。以下是脚本的一部分: #!/bin/sh set -e trap 'true' USR1 # ... gunzip -c "${SVM_IMAGE_FILE_PATH}" | dd iflag=fullblock of="${TARGET_DEVICE_PATH}" bs=64M 2>"${DD_OUTPUT_FILE_PATH}" & DD_P
.gz
文件并将其复制到块设备中。我使用dd
获取有关进度的信息(我不能使用其他实用程序,如pv
来实现这一点)。以下是脚本的一部分:
#!/bin/sh
set -e
trap 'true' USR1
# ...
gunzip -c "${SVM_IMAGE_FILE_PATH}" | dd iflag=fullblock of="${TARGET_DEVICE_PATH}" bs=64M 2>"${DD_OUTPUT_FILE_PATH}" &
DD_PID=$!
echo "Decompression process has started: $$ -> ${DD_PID}" >> "${DECOMPRESSION_LOG_FILE_PATH}"
# Wait for dd process to become ready to receive 'kill -s USR1' signals
sleep 1
while (ps -p "${DD_PID}") >/dev/null 2>&1
do
set +e
kill -s USR1 $DD_PID 2>/dev/null
LAST_LINE=`tail -n 1 "${DD_OUTPUT_FILE_PATH}"`
case "${LAST_LINE}" in
*byte*)
BYTES_COPIED=`echo ${LAST_LINE} | cut -d ' ' -f1`
PROGRESS=$(( $(( $BYTES_COPIED * 100 )) / $DECOMPRESSED_FILE_SIZE ))
set_status "${PROGRESS}% processed"
;;
esac
# ...
set -e
sleep 1
done
如您所见,在while
循环之前有一个stragesleep 1
。我想摆脱它,但我不知道如何摆脱。如果我删除此sleep 1
,则dd
进程将在第一次调用kill-s USR1$dd_PID
后立即被终止。也许这并没有杀死dd,但它在某种程度上影响了gunzip进程,我不知道到底发生了什么
那么,有没有办法摆脱这种睡眠状态呢?有两个问题:
DD\u PID
是运行管道的shell的PID,而不是DD
SIGUSR1
将在进程未准备好接收信号时终止进程dd
,但这不是您可以依赖的(尤其是在使用/bin/sh
时)
您也不能依靠dd
赛车来设置信号陷阱,因此最好自己设置
<> P>既然您在Linux上,请考虑只使用GNU DD标志<代码>状态=进度< /代码>自动状态栏。
或者,将shebang更改为#!/bin/bash
,并使用:
trap '' USR1 # Ignore USR1 in inherited processes by default
dd iflag=fullblock of="${TARGET_DEVICE_PATH}" bs=64M 2>"${DD_OUTPUT_FILE_PATH}" \
< <(gunzip -c "${SVM_IMAGE_FILE_PATH}") &
dd_pid=$! # Is now 'dd's pid and not a shell's.
或者使用
dash
,将shebang改为#!/bin/dash
,并将trap'true'USR1
改为trap'USR1看看@ccarton谢谢!看来sleep 1
实际上是一个合法的解决方案:)但我想,如果有人想出一个聪明的解决办法,我会把这个问题留到一边:)谢谢你的回答!1.我将$DD|u PID与ps aux | grep DD
中的PID进行了比较,它们匹配。2.我必须使用的dd
版本没有标记status=progress
3。由于遗留问题,我不能简单地切换到#/在我的脚本中,bin/bash
,但我必须使用#/bin/sh
,例如,它恰好是Debian=)4中的破折号。顺便说一句,出于某种原因,我不得不编写trap'true'USR1
,而不是trap'USR1
,以使脚本正常工作。我也无法解释这种现象;)5.我两个都不能用/bin/bash
或#/箱子/破折号
。我必须使用#/bin/sh
由于遗留原因。在某些系统中#/bin/sh
实际上可能是#/bin/bash
,但我不能相信这一点。无论如何,你已经为我做了很多,我不能不投票就留下你的帮助性评论。谢谢@皮克斯:当然,你更了解你的传统系统。
fifo="/tmp/foo"
mkfifo "$fifo"
gunzip -c "${SVM_IMAGE_FILE_PATH}" | {
trap '' USR1
dd iflag=fullblock of="${TARGET_DEVICE_PATH}" bs=64M 2>"${DD_OUTPUT_FILE_PATH}" &
echo "$!" > "$fifo"
wait
} &
read dd_pid < "$fifo"
rm "$fifo"