42

在 Linux 中,我们可以做

dd if=/dev/sdb of=bckup.img

但是如果磁盘是 32GB,只使用了 4GB,那么 32GB 的图像文件就是浪费空间。是否有任何方法或工具可以仅使用有效数据创建图像?

4

7 回答 7

46

处理这个问题的非常好的和简单的方法是简单地通过 gzip 进行管道传输,如下所示:

# dd if=/dev/sdb | gzip > backup.img.gz

这样,您的图像将被压缩,并且很可能未使用的空间将被压缩到几乎没有。

您将使用它来恢复此类图像:

# cat backup.img.gz | gunzip | dd of=/dev/sdb

注意:如果您最近删除了很多文件,则图像大小可能仍然很大(删除文件不一定会使底层扇区归零)。您可以通过创建并立即删除包含零的大文件来擦除可用空间:

# cd /media/flashdrive
# dd if=/dev/zero of=bigfile bs=1M     # let it run and quit by disk full error
# rm bigfile
于 2013-10-14T07:22:03.893 回答
15

最好的办法是

  1. 从保留元数据的所有分区中复制所有文件

    mkdir -p myimage/partition1

    mkdir myimage/partition2

    sudo cp -rf --preserve=all /media/mount_point_partition1/* myimage/partition1/

    sudo cp -rf --preserve=all /media/mount_point_partition2/* myimage/partition2/

  2. 提取 MBR

    sudo dd if=/dev/sdX of=myimage/mbr.img bs=446 count=1

    更换/dev/sdX相应的设备。

  3. 将目标磁盘分区为大小大于复制数据的分区,并且应该使用相同的格式和相同的标志gparted。谷歌如何对磁盘进行分区。

  4. 挂载新格式化和分区的磁盘。在大多数计算机上,您只需连接磁盘,即可在/media文件夹中找到已安装的分区。

  5. 使用以下命令将先前复制的数据复制到目标分区

    sudo cp -rf --preserve=all myimage/partition1/* /media/mount_point_partition1/

    sudo cp -rf --preserve=all myimage/partition2/* /media/mount_point_partition2/

  6. 复制回 MBR

    sudo dd if=myimage/mbr.img of=/dev/sdX bs=446 count=1

现在享受你的新磁盘!

于 2014-04-29T16:12:34.447 回答
5

使用 的bscount参数dd,您可以限制图像的大小,如答案 1665017的步骤 2 所示。

您可能已经知道要创建什么尺寸的图像。如果没有,您可以从以下方面获得一个好主意df

df -H --total /

替换/为与磁盘分区相关的所有挂载点的空格分隔列表。

更准确的方法可能是使用fdisk或您喜欢的分区编辑器并忙于使用计算器。

$ fdisk -l /dev/mmcblk0

Disk /dev/mmcblk0: 7.4 GiB, 7948206080 bytes, 15523840 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00057540

Device         Boot  Start     End Sectors  Size Id Type
/dev/mmcblk0p1        2048  186367  184320   90M  c W95 FAT32 (LBA)
/dev/mmcblk0p2      186368 3667967 3481600  1.7G  5 Extended
/dev/mmcblk0p5      188416 3667967 3479552  1.7G 83 Linux

以字节为单位的总已用空间 = 最后一个分区的结束扇区 X 扇区大小(此处为 3667967 x 512)。

以 GB 为单位的总已用空间 = 以字节为单位的总已用空间 / 1024 3(此处为 1.749023 GB)。

例如,如果您决定您的映像应该正好是 2 GB,则以下命令将执行此操作:

dd if=/dev/mmcblk0 of=/path/to/pi_updated.img bs=1M count=2048

生成的图像还将包括超出最后一个分区最大范围的随机噪声。

sudo如果您的帐户还没有足够的权限,请不要忘记上述命令。

出于我的目的,我不需要完美修剪到最后一点数据的图像,因此当实际大小为 1.75 GB 时,2 GB 的图像对我来说就足够了。这会减少映像中其他 6 GB(或 30 GB 或任何设备有空闲的空间)的未使用空间。

我在很多地方都看到了dd应该在已挂载的分区上执行的建议,我遵循了这些建议,因为它看起来直观正确;它看起来更像是试图勾勒自己在镜子中制作草图,而您正在制作的草图在草图中也可见。这有点粗略。

于 2014-11-13T13:25:51.177 回答
3

在尝试了多种不同的方法后,我发现了以下文章:

https://medium.com/platformer-blog/creating-a-custom-raspbian-os-image-for-production-3fcb43ff3630

它的创建是为了缩小和调整(在第一次启动时)树莓派图像的大小,但可以很容易地针对任何其他 Linux 发行版进行调整。我成功地让它与 Debian 9 一起在基于 arm 的定制芯片上工作。

pishrink脚本rc.local创建的首先raspi-config用于调整 rootfs 的大小,然后回退到使用的方法parted(我必须提前在我的机器上安装)。我注释掉.raspi-config

我的 sd 卡映像从 15 GB 缩小到 1.1 GB。我用etcher 刷新了缩小的 sd-card 图像。完整的 15 GB 映像耗时不到 5 分钟,而不是半小时以上

于 2019-09-17T20:47:55.527 回答
2

如果您有一张 16 GB、32 GB 等的大型 SD 卡,但您想通过备份节省空间,您可以使用:

sudo apt-get install gnome-disk-utility

打开磁盘实用程序来检查你的 U 盘是否真的有:

gnome-disks

在我的例子中,一张带有 Raspbian 映像的 32GB SD 卡被识别为:/dev/sde

所以我运行/dev/sde

sudo dd bs=4M status=progress if=/dev/sde | gzip > \
/you-selected-full-path-here/raspberry-images/`date +%Y%m%d`_rpi_image_backup.gz
status=progress gives you progress bar indication
| gzip > compresses the 32 GB total size and not writing the empty space from the 32 GB
`date +%Y%m%d` writes today date in the filename

输出:20190529_rpi_image_backup.gz

而且大小只有3.5GB。如果您想将此图像写入新的 SD 卡,请使用:

https://www.balena.io/etcher/

您也可以将这个由 32 GB 制作的图像写入 16 GB 或 8 GB 的磁盘,不再抱怨图像太大了。

于 2019-05-30T08:42:10.477 回答
1

我制作自定义 raspios 图像的解决方案:

DIR="./img"
DEVICE=/dev/sdb

# declare custom copy functions
copy() {
  echo "[$1] copy $2 to $3..."
  if [ "$1" == 'ext' ]; then
    sudo rsync -aHAXX \
      --no-inc-recursive \
      --numeric-ids \
      --filter='-x security.selinux' \
      --delete \
      --exclude={"/lost+found"} \
      --info=progress2 \
      $2 \
      $3
  else
    sudo rsync -rtD \
      --modify-window=1 \
      --no-inc-recursive \
      --delete \
      --exclude={"/lost+found"} \
      --info=progress2 \
      $2 \
      $3
  fi
}

# create working directories
mkdir -p $DIR/{mount,image}/{boot,rootfs}

# mount initial device partitions
sudo mount ${DEVICE}1 $DIR/mount/boot
sudo mount ${DEVICE}2 $DIR/mount/rootfs

# preserve partitions UUIDs
PTUUID=0x`sudo blkid -p $DEVICE | sed -e 's/.*PTUUID="\([0-9a-f]*\)".*/\1/'`
BOOTUUID=`sudo blkid -p ${DEVICE}1 | sed -e 's/.* UUID="\([0-9a-zA-Z\-]*\)".*/\1/' | tr -d '-'`
ROOTUUID=`sudo blkid -p ${DEVICE}2 | sed -e 's/.* UUID="\([0-9a-zA-Z\-]*\)".*/\1/'`

# copy contents from physical device to local folder
copy fat $DIR/mount/boot/   $DIR/image/boot/
copy ext $DIR/mount/rootfs/ $DIR/image/rootfs/
umount ${DEVICE}1
umount ${DEVICE}2

# show contents size
BOOTSIZE=`sudo du -hs $DIR/image/boot`
ROOTSIZE=`sudo du -hs $DIR/image/rootfs`
echo "boot is $BOOTSIZE"
echo "root is $ROOTSIZE"

# allocate the final .img file
# change size as needed
SIZE="5"
echo "allocating ${SIZE}G image..."
rm $DIR/$IMAGE
fallocate -l ${SIZE}G $DIR/$IMAGE

# create partitions
echo "formatting image..."
sed -e 's/\s*\([\+0-9a-zA-Z]*\).*/\1/' << EOF | fdisk $DIR/$IMAGE > /dev/null
o          # create MBR partition scheme
n          # new partition
p          # primary
1          # partition #1
8192       # start block
532479     # end block
t          # define type
0c         # W95 FAT32 (LBA)
n          # new partition
p          # primary
2          # partition #2
532480     # start block
           # last end block
t          # define type
2          # for partition #2
83         # linux
x          # advanced menu
i          # change disk identifier
$PTUUID    # identifier from original fstab
r          # return to normal menu
w          # write changes
EOF

# locally mount the .img
echo "mounting image..."
LOOP=`sudo losetup -fP --show $DIR/$IMAGE`
echo "mounted image under $LOOP"
ls -la $LOOP*

echo "creating partition boot with FAT32"
sudo mkfs.fat \
  -F 32 \
  -S 512 \
  -i $BOOTUUID \
  -n boot \
  ${LOOP}p1

echo "creating partition rootfs with ext4"
sudo mkfs.ext4 \
  -b 4096 \
  -U $ROOTUUID \
  -L rootfs \
  ${LOOP}p2

echo "mounting image loops"
sudo mount ${LOOP}p1 $DIR/mount/boot
sudo mount ${LOOP}p2 $DIR/mount/rootfs

echo "copying contents to image"
copy fat $DIR/image/boot/   $DIR/mount/boot/
copy ext $DIR/image/rootfs/ $DIR/mount/rootfs/

echo "unmounting image"
unmount "$LOOP+" > /dev/null
echo "removing loop"
sudo losetup -d ${LOOP}
于 2021-05-07T16:45:27.077 回答
1

稀疏(缩小)图像克隆说明:

将可启动的 Ubuntu 持久 live USB 与 usbdata 分区中的图像文件插入单板计算机,例如 UP² Board。引导至 USB(默认持久实时选项)。启动终端并输入以下命令(单行):

sudo dd if=/media/ubuntu/usbdata/ubuntu.img of=/dev/mmcblk0 bs=1M status=progress

等待 15-20 分钟。完成后,关闭并断开 USB。引导至内部 eMMC 驱动器

创建图像:

从内部 eMMC 创建未压缩的稀疏图像文件并保存到闪存驱动器

sudo dd if=/dev/mmcblk0 bs=1M status=progress | cp --sparse=always /dev/stdin /media/ubuntu/usbdata/ubuntu.img

将未压缩的图像文件提取到内部 eMMC

sudo dd if=/media/ubuntu/usbdata/ubuntu.img of=/dev/mmcblk0 bs=1M status=progress

从内部 eMMC 创建压缩图像文件并保存到桌面

sudo dd if=/dev/mmcblk0 bs=1M status=progress | gzip > /home/user/Desktop/ubuntu.img.gz

将压缩图像文件提取到内部 eMMC

sudo gzip -cd /home/user/Desktop/ubuntu.img.gz | dd of=/dev/mmcblk0 bs=1M status=progress

资料来源: http ://dustymabe.com/2012/11/15/create-a-disk-image-without-enough-free-space/ https://forum.up-community.org/discussion/1197/solved-克隆上板的图像

要从 Linux 中修改现有 Linux 映像或驱动器,请插入驱动器或挂载映像:

sudo mkdir /media/root
sudo mount -t ext4 -o loop,offset=537919488 /media/user/usbdata/ubuntu.img  /media/root

要确定映像或驱动器的偏移量,请运行:

fdisk -l /media/user/usbdata/ubuntu.img

然后,将 512 字节的块大小乘以 Linux 分区的起始块 1050624。512*1050624 = 537,919,488

同时挂载其他系统文件夹:

for i in /dev /dev/pts /proc /sys /run; do sudo mount -B $i /media/root$i; done

然后 cd 进入 img 和 chroot 的根文件夹:

cd /media/root
sudo chroot .

然后您可以更新文件、密码等。要卸载,请运行:

for i in /dev /dev/pts /proc /sys /run; do sudo umount /media/root$i; done
sudo umount /media/root

创建 Ubuntu 持久实时 USB 映像 按照以下步骤使用 Ubuntu 的持久实时安装来刷新 USB 驱动器:https ://www.howtogeek.com/howto/14912/create-a-persistent-bootable-ubuntu-usb-flash-驾驶/

于 2021-04-08T23:25:38.087 回答