dd图像到SD卡完了,SD卡还在忙

时间:2017-02-02 04:47:24

标签: bash shell command-line dd

如果我使用dd将* .img文件恢复到SD卡,它可以正常工作。如果我在dd完成后立即尝试安全地移除(弹出鹦鹉螺)SD卡,会弹出一条通知,上面写着:“正在写入SD卡”。读卡器上的LED也闪烁。它需要几分钟才能取出卡。第一个问题是,怎么会这样?

我在bash脚本中使用dd。脚本完成后,应该可以删除SD卡。第二个问题是,我可以以某种方式检查SD卡的状态,这意味着是否忙碌?

编辑20170203: 这是脚本。目的只是恢复树莓派备份。

#!/bin/bash
#
#enter path of image
IMG=$(whiptail --inputbox "Enter path to image." 8 78 "$HOME/Downloads/raspberry_backup.img.gz" --title "Name" 3>&1 1>&2 2>&3)

exitstatus=$?
if [ $exitstatus != 0 ]; then
    echo "INFO: User abort."
    exit 1
fi

#check for dependencies
if [ -z "$(which parted 2> /dev/null)" ] || [ -z "$(which gzip 2> /dev/null)" ]; then
    if (whiptail --title "Dependencies" --yesno "This script need parted and gzip. One or more are not installed. Install now?" 8 78) then
        sudo dnf install -y parted gzip
    else
        exit 1
    fi
fi

#show information of drives
whiptail --scrolltext --title "Info about mounted devices:" --msgbox "$(sudo parted -l -m init G print | grep /dev/sd | cut -d: -f1,2)" 8 78

#enter drive name
DEV=$(whiptail --inputbox "Enter Device Name." 8 78 /dev/sd --title "Device Name" 3>&1 1>&2 2>&3)

exitstatus=$?
if [ $exitstatus != 0 ]; then
    echo "INFO: User abort."
    exit 1
fi

#check for /dev/sd* vaidity
if [[ $DEV != "/dev/sd"* ]]; then
    echo "ERROR: ${DEV} is not valid."
    exit 1
fi

#if restore image is *.gz then uncomress first
if [[ "$IMG" == *".gz" ]]; then
    (pv -n ${IMG} | gzip -d -k > $HOME/raspberry_restore.img) 2>&1 | whiptail --gauge "Please wait while uncompressing image..." 6 50 0
    IMG=$HOME/raspberry_restore.img
fi

if [[ "$IMG" == *".img" ]]; then
    SIZEDD=$(sudo parted -m $IMG unit B print | grep ext4 | cut -d: -f3 | cut -dB -f1)
    (sudo dd if=$IMG bs=1M | pv -n --size $SIZEDD | sudo dd of=$DEV bs=1M) 2>&1 | whiptail --gauge "Please wait while restoring image to SD card..." 6 50 0
else
    echo "ERROR: Not an *.img file"
    exit 1
fi

sudo rm $HOME/raspberry_restore.img

#show information
whiptail --title "Restore finished." --msgbox "Restored to path: "$DEV"" 8 78
exit 1

由于

3 个答案:

答案 0 :(得分:3)

fsync()系统调用将导致刷新操作系统级别的任何写入缓存。虽然可以用C语言编写一些东西来为shell中的特定块设备调用它,但是在shell中最简单的方法是使用sync命令刷新所有文件系统和设备中的所有挂起写入:

sync

或者,您可以通过传递dd告诉O_SYNC使用oflag=sync标志,防止dd退出,直到写入持久存储到磁盘:

# note that oflag is a GNU extension, not found on MacOS/BSD
dd oflag=nocache,sync of="$DEV" bs=1M

如果您知道SD卡的原生块大小,请考虑改为使用O_DIRECT

# 4k is a reasonable guess on block size; tune based on your actual hardware.
dd oflag=direct of="$DEV" bs=4K

答案 1 :(得分:1)

我建议您使用此处描述的非常快速的perl脚本:https://askubuntu.com/a/216628

我有时也会使用自己来查找不需要的/隐藏/未知的进程,以保持资源的繁忙。

完成此过程后,可以调查保持SSD忙碌的内部行为。

答案 2 :(得分:0)

如果正在使用设备,您可以使用lsof。如果您的SD卡标识为/dev/sdd

lsof /dev/sdd 2>/dev/null && echo "device is busy"
相关问题