我想在后台运行多个dd命令,但能够看到状态。
我有下面的script.sh
:
#!/usr/bin/env bash
for drive in $@
do
echo "Wiping $drive"
dd if=/dev/zero of=$drive status=progress &
done
wait
echo "Done."
这将产生以下输出:
$ sudo bash ./script.sh /dev/sda /dev/sdb
Wiping /dev/sda
Wiping /dev/sdb
288788992 bytes (289 MB, 275 MiB) copied, 10 s, 28.9 MB/s 14404864 bytes (114 MB, 109 MiB) copied, 4 s, 28.6 MB/s
是否有办法在驱动器路径下输出相应的dd状态?例如:
$ sudo bash ./script.sh /dev/sda /dev/sdb
Wiping /dev/sda
288788992 bytes (289 MB, 275 MiB) copied, 10 s, 28.9 MB/s
Wiping /dev/sdb
14404864 bytes (114 MB, 109 MiB) copied, 4 s, 28.6 MB/s
我尝试了各种重定向,命名管道等,但无法实现这样(或类似)的输出。
2条答案
按热度按时间rwqw0loc1#
将每个
dd
的状态重定向到一个文件,并在清除旧输出的同时重复打印这些文件。GNU coreutils的
dd status=progress
将其状态打印到stderr,因此使用2>
重定向状态信息。状态的更新是用
\r
覆盖当前行,然后是新的状态。由于\r
只适用于单行,更新四个不同的行需要终端控制序列,例如ANSI转义码,可以使用clear
和tput
等命令方便地打印出来。如果您正在擦除许多大的或慢的驱动器,上面的代码是低效的,因为状态文件不断增长(即使它们 * 似乎 * 只包含一行),我们不断地打印这些增长的文件一遍又一遍。
如果你遇到问题,试着增加睡眠时间。也许
sed 's/.*\r//'
代替sed ''
可以加快速度。tail -c100
肯定会有帮助,但是会在输出中插入临时文件名。正确的处理方法应该是...
mkfifo
命令)。status=progress
并定期...dd
作业调用kill -s USR1
,这使得它们打印单个状态行。
dd
作业会运行,而其他作业已经完成并关闭了它们的fifos,这使得这个过程有点复杂,这是我坚持使用文件来回答这个问题的主要原因。4xy9mtcn2#
使用协进程,您可以执行以下操作
我的
dd
没有status
,所以我假设dd
添加了\r
,而不是\n
。