คัดลอกการติดตั้ง Raspbian ที่มีอยู่ไปยังการ์ด SD ขนาดเล็ก


25

เป็นไปได้หรือไม่ที่จะคัดลอกการติดตั้ง Raspbian ที่มีอยู่และกำหนดค่าไปยังการ์ด SD ขนาดเล็ก?

เมื่อฉันติดตั้ง Raspbian ครั้งแรกฉันมีการ์ดขนาด 32 GB ที่เห็นได้ชัดว่าใหญ่กว่าที่ต้องการ


ระบบจะทำงานได้ดีขึ้นและการ์ดจะมีพื้นที่ว่างนานขึ้นในพาร์ติชันหลักของคุณดังนั้นอย่าลดขนาดมันมากเกินไป - ให้ใช้งานอย่างน้อยสองเท่า (เช่นหากระบบของคุณมีขนาด 2-3 GB ใช้ การ์ด 8GB และขยายพาร์ติชันเพื่อเติมเต็มพื้นที่ว่างทั้งหมด) โปรดทราบว่าหากคุณไม่ได้ขยายพาร์ติชันเพื่อเริ่มต้นมันจะไม่เป็น 32 GB ดังนั้นคุณอาจไม่ต้องลดขนาดพาร์ติชัน
goldilocks

ขอบคุณที่ชี้ให้เห็นถึงสิ่งนี้ แต่ราสเบอร์รี่ของฉันกำลังใช้งานเพียง 1.8 GB เนื่องจากเป็นการติดตั้งขั้นพื้นฐานจริงๆ ดังนั้นฉันเดา 4 GB ควรจะเพียงพอ
mwld

ฉันคิดว่าฉันโตขึ้นเป็นขนาดเต็มเมื่อฉันติดตั้ง Debian Wheezy เป็นครั้งแรก ตอนนี้ฉันย่อขนาดเหลือ 2.5 GB แต่ก็ยังไม่สำเร็จ ดูความคิดเห็นของฉันด้านล่าง
mwld

ซ้ำใกล้เคียง: raspberrypi.stackexchange.com/q/29947/5538
goldilocks

1
หากหนึ่งในคำตอบด้านล่างตรงกับคำถามของคุณโปรดตรวจสอบคำตอบ
โหมด Wes

คำตอบ:


12

ในคำตอบนี้ฉันแสดงให้เห็นถึงสิ่งที่ต้องทำทีละขั้นตอนเพื่อให้ผู้คนเข้าใจตรรกะที่อยู่เบื้องหลังการแก้ปัญหาและเพื่อให้สามารถใช้ขั้นตอนในปัญหาอื่น ๆ ของพวกเขาได้

แต่ประการแรกมันควรจะระบุว่ามันเป็นปัญหาทั่วไป (ไม่ใช่เฉพาะ raspi) เพื่อโยกย้ายระบบไฟล์จากการ์ด SD ไปยังการ์ด SD ที่เล็กกว่า (แต่ใหญ่พอสำหรับข้อมูล)

ความต้องการ

แล็ปท็อปที่มีตัวอ่านการ์ด micro SD และ Linux (ฉันชอบ Ubuntu)

ตัวย่อ

PIBOX      : Raspberry Pi which is used
SD_CARD_A  : 8GB micro SD card which is used on PIBOX and on which Raspbian-lite (the OS) is installed
SD_CARD_B  : 2GB micro SD card which will be used on PIBOX and on which Raspbian-lite (the OS) will be installed

พาร์ติชันของ SD_CARD_A

ในขณะที่ PIBOX กำลังทำงานเราจะแสดงรายการพาร์ติชัน (พาร์ติชันระบบที่ไม่จำเป็นจะไม่แสดงที่นี่)

root@pibox:~# df -Th
Filesystem     Type      Size  Used Avail Use% Mounted on
/dev/root      ext4      7.3G  1.1G  5.9G  16% /
/dev/mmcblk0p1 vfat       63M   21M   43M  33% /boot

มี 2 พาร์ติชันบน SD_CARD_A เช่นเดียวกับและ/ /bootแม้ 2GB ไม่ได้ใช้ทั้งหมด

สำรอง SD_CARD_A

หลังจากที่เราปิดและหยุด PIBOX เราจะนำ SD_CARD_A ออกจากบอร์ด PIBOX และใส่ลงในเครื่องอ่านการ์ดของแล็ปท็อปของเรา

พาร์ติชันของ SD_CARD_A จะถูกติดตั้งโดยอัตโนมัติเพื่อให้ระบบของเราเป็นและ/dev/sdc1/dev/sdc2

root@mylaptop:~# df -Th
Filesystem                    Type      Size  Used Avail Use% Mounted on
/dev/sdb2                     ext4       22G   13G  7.9G  63% /
/dev/sdb1                     vfat      197M  2.6M  195M   2% /boot/efi
/dev/sda8                     ext4       66G   11G   52G  17% /home
/dev/sdc1                     vfat       63M   21M   43M  33% /media/some_user_name/boot
/dev/sdc2                     ext4      7.3G  1.1G  5.9G  16% /media/some_user_name/some_uuid_serial

เราเลิกเมานท์พาร์ติชั่นเหล่านั้นจากระบบของเราเพื่อทำงานให้สำเร็จ

root@mylaptop:~# umount /dev/sdc1
root@mylaptop:~# umount /dev/sdc2

เราแสดงข้อมูลอุปกรณ์ของ SD_CARD_A ในรายละเอียดสำหรับการยืนยันในขั้นตอนต่อไป

root@mylaptop:~# fdisk -l /dev/sdc
Disk /dev/sdc: 7969 MB, 7969177600 bytes
246 heads, 62 sectors/track, 1020 cylinders, total 15564800 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
Disk identifier: 0x2019f6d8

   Device Boot      Start         End      Blocks   Id  System
/dev/sdc1            8192      137215       64512    c  W95 FAT32 (LBA)
/dev/sdc2          137216    15564799     7713792   83  Linux

ด้านบนคุณจะเห็นว่า SD_CARD_A มีความจุ 8GB

เราโคลน SD_CARD_A ลงในไฟล์ pibox.img

root@mylaptop:~# dd bs=4MB if=/dev/sdc of=pibox.img
1992+1 records in
1992+1 records out
7969177600 bytes (8.0 GB) copied, 416.582 s, 19.1 MB/s

ตรวจสอบขนาดของไบต์ที่ถูกคัดลอกซึ่งเท่ากับค่าที่เราได้รับจากfdisk -l /dev/sdcคำสั่ง

โมดูลวนรอบ Linux

Linux มีโมดูลที่เรียกว่า loopback ซึ่งช่วยให้เราสามารถจัดการไฟล์เป็นอุปกรณ์บล็อกได้

เราโหลดโมดูลลูปแบ็ค

root@mylaptop:~# modprobe loop

เราพบเส้นทางอุปกรณ์วนรอบที่ไม่ได้ใช้

root@mylaptop:~# losetup -f /dev/loop0

ตอนนี้เราสร้างอุปกรณ์ลูปแบ็คสำหรับไฟล์ pibox.img

root@mylaptop:~# losetup /dev/loop0 pibox.img

เราเรียกเคอร์เนลเกี่ยวกับการเปลี่ยนแปลงพาร์ติชัน

root@mylaptop:~# partprobe /dev/loop0

เรายืนยันว่าการดำเนินการก่อนหน้านี้สำเร็จหรือไม่

root@mylaptop:~# losetup /dev/loop0
/dev/loop0: [0806]:69 (/root/pibox.img)

เราแสดงข้อมูลอุปกรณ์ลูปแบ็คในรายละเอียดเพื่อเปรียบเทียบกับ SD_CARD_A

root@mylaptop:~# fdisk -l /dev/loop0
Disk /dev/loop0: 7969 MB, 7969177600 bytes
255 heads, 63 sectors/track, 968 cylinders, total 15564800 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
Disk identifier: 0x2019f6d8

      Device Boot      Start         End      Blocks   Id  System
/dev/loop0p1            8192      137215       64512    c  W95 FAT32 (LBA)
/dev/loop0p2          137216    15564799     7713792   83  Linux

ด้านบนคุณจะเห็นว่าขนาดอุปกรณ์ลูปแบ็ค (= 7969177600 ไบต์) และพาร์ทิชันเหมือนกันกับของ SD_CARD_A

คณิตศาสตร์พื้นฐาน

/dev/loop0p2จากนี้ไปเราจะมุ่งเน้นไปที่พาร์ทิชัน Let 's ชื่อTHE_PARTITION

ขนาดบล็อกคือ 512 ไบต์ (ตามที่พิมพ์บนบรรทัดที่เริ่มต้นด้วย Units = sector ..... )

THE_PARTITION เริ่มจากบล็อก 137216 และสิ้นสุดที่บล็อก 15564799 ซึ่งหมายความว่ามันมีขนาดเท่ากับ15427584 blocks(= 15564799 - 137216 + 1)

ดังนั้นขนาดของ THE_PARTITION หน่วยเป็นไบต์7898923008 bytes(= 512 * 15427584)

เพื่อให้พอดีกับ THE_PARTITION ใน SD_CARD_B เราต้องการให้มีขนาดใหม่ 3710940 blocksหรือในคำอื่น ๆ1900001280 bytes(= 512 * 3710940)

ดังนั้นเลขท้ายบล็อกใหม่จะ3848155คำนวณได้จากstart block number(= 137216) + size in blocks(= 3710940) 1-

ระบบไฟล์เทียบกับพาร์ติชัน

มีการดำเนินการ 2 รายการที่ไม่ควรเข้าใจผิดซึ่งกันและกัน

  • การปรับขนาดระบบไฟล์ เราจะหดตัวระบบไฟล์ใน THE_PARTITION 3710940 blocksโดยการตั้งค่าขนาดของมันไป
  • การปรับขนาดพาร์ติชัน เราจะหดตัว THE_PARTITION 3848155โดยการตั้งค่าเลขท้ายบล็อกของตนเพื่อ

ย่อขนาดระบบไฟล์

e2fsckก่อนที่หดตัวระบบไฟล์ก็ควรจะทำเครื่องหมายว่าเป็นที่สะอาดโดย

root@mylaptop:~# e2fsck -f /dev/loop0p2
e2fsck 1.42.9 (4-Feb-2014)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/loop0p2: 41175/475776 files (0.2% non-contiguous), 309183/1928448 blocks

resize2fsเราหดตัวระบบไฟล์ที่มี

root@mylaptop:~# resize2fs /dev/loop0p2 3710940s
resize2fs 1.42.9 (4-Feb-2014)
Resizing the filesystem on /dev/loop0p2 to 463867 (4k) blocks.
The filesystem on /dev/loop0p2 is now 463867 blocks long.

ลดขนาดพาร์ติชัน

เราเรียนรู้ว่าหมายเลข THE_PARTITION นั้นคือpartedอะไร

root@mylaptop:~# parted /dev/loop0
GNU Parted 2.3
Using /dev/loop0
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print                                                            
Model: Loopback device (loop)
Disk /dev/loop0: 7969MB
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start   End     Size    Type     File system  Flags
 1      4194kB  70.3MB  66.1MB  primary  fat16        lba
 2      70.3MB  7969MB  7899MB  primary  ext4

(parted) quit

เราหด THE_PARTITION partedกับ

root@mylaptop:~# parted /dev/loop0 unit s resizepart 2 3848155
Warning: Shrinking a partition can cause data loss, are you sure you want to continue?
Yes/No? Yes  

เราทำด้วยอุปกรณ์ลูปแบ็ค เราถอดมันออก

root@mylaptop:~# losetup -d /dev/loop0

ตัดไฟล์รูปภาพ

เราตรวจสอบตารางพาร์ติชันใหม่

root@mylaptop:~# fdisk -l pibox.img 

Disk pibox.img: 7969 MB, 7969177600 bytes
255 heads, 63 sectors/track, 968 cylinders, total 15564800 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
Disk identifier: 0x2019f6d8

    Device Boot      Start         End      Blocks   Id  System
pibox.img1            8192      137215       64512    c  W95 FAT32 (LBA)
pibox.img2          137216     3848155     1855470   83  Linux

ในการส่งออกก็จะเห็นได้อย่างชัดเจนว่าเลขท้ายบล็อกของ THE_PARTITION from 15564799 to 3848155จะลดลง

3848155บล็อกสุดท้ายที่เราใช้เป็น การกำหนดหมายเลขบล็อกเริ่มต้นจาก 0 ดังนั้นเรามี 3848155 + 1 บล็อกทั้งหมดและขนาดใหม่ของไฟล์ pibox.imgควรเป็น1970255872 bytes (= (3848155 + 1) * 512)

เราตัดทอนไฟล์ pibox.img

root@mylaptop:~# truncate --size=1970255872 pibox.img

เราตรวจสอบขนาดใหม่ของไฟล์ pibox.img

root@mylaptop:~# ls -l pibox.img 
-rw-r--r-- 1 root root 1970255872 Oct 13 21:53 pibox.img

สร้าง SD_CARD_B

เราใส่ SD_CARD_B ลงในเครื่องอ่านการ์ดของแล็ปท็อปของเรา พาร์ติชันของ SD_CARD_B จะถูกติดตั้งโดยอัตโนมัติเพื่อให้ระบบของเราเป็นและ/dev/sdc1/dev/sdc2

root@mylaptop:~# df -Th
Filesystem                    Type      Size  Used Avail Use% Mounted on
/dev/sdb2                     ext4       22G   13G  7.9G  63% /
/dev/sdb1                     vfat      197M  2.6M  195M   2% /boot/efi
/dev/sda8                     ext4       66G   11G   52G  17% /home
/dev/sdc1                     vfat       63M   21M   43M  33% /media/some_user_name/boot
/dev/sdc2                     ext4      1.8G  1.6G   59M  97% /media/some_user_name/some_uuid_serial

ด้านบนคุณจะเห็นว่า SD_CARD_B มีความจุ 2GB

เราเลิกเมานท์พาร์ติชั่นเหล่านั้นจากระบบของเราเพื่อทำงานบน SD_CARD_B ได้สำเร็จ

root@mylaptop:~# umount /dev/sdc1
root@mylaptop:~# umount /dev/sdc2

เราโคลนไฟล์ pibox.img ลงใน SD_CARD_B

root@mylaptop:~# dd bs=4MB if=pibox.img of=/dev/sdc
492+1 records in
492+1 records out
1970255872 bytes (2.0 GB) copied, 646.967 s, 3.0 MB/s

ตรวจสอบขนาดของไบต์ที่ถูกคัดลอกซึ่งเท่ากับค่าที่เราได้รับจากls -l pibox.imgคำสั่ง

กำลังเริ่ม PIBOX

หลังจากที่เรานำ SD_CARD_B ออกจากแล็ปท็อปของเราและใส่ไว้ในบอร์ด PIBOX เราจะบู๊ตระบบและลงชื่อเข้าใช้ในคอนโซล PIBOX

เราจะแสดงรายการพาร์ติชั่น (พาร์ติชั่นระบบที่ไม่จำเป็นอื่น ๆ จะไม่ปรากฏที่นี่)

root@pibox:~# df -Th
Filesystem     Type      Size  Used Avail Use% Mounted on
/dev/root      ext4      1.8G  1.1G  601M  64% /
/dev/mmcblk0p1 vfat       63M   21M   43M  33% /boot

สิ่งที่ดี. ฉันคิดว่าสิ่งของบางอย่างของคุณด้วยการตั้งค่าลูปแบ็คอาจยืดยาวและไม่จำเป็นคุณอาจต้องการลองดู สิ่งที่คล้ายกันมากจากคำถามที่คล้ายกันมาก: raspberrypi.stackexchange.com/a/29952/5538
goldilocks

@ goldilocks ไม่ได้ทดสอบ แต่ฉันคิดว่าการใช้ loopback เป็นสิ่งที่จำเป็น เท่าที่ฉันรู้ว่าการแยกส่วนไม่สามารถทำงานกับไฟล์ภาพได้โดยตรงมันต้องมีส่วนต่อประสานอุปกรณ์สำหรับการทำงานของมัน
vaha

ใช่ แต่ฉันคิดว่าคุณจะพบว่าคุณจะได้ไม่ต้องรำคาญกับหรือแม้กระทั่งlosetup -o loop=whateverตามโพสต์อื่นฉันใช้mount -o offset=123 /imagefilepath /mntpointและการใช้ loopback นั้นโดยปริยาย ฉันเข้าใจว่าโดยทั่วไปแล้วใน linux ตอนนี้ลองและดู จากนั้นคุณสามารถลดขนาดลงเหลือเพียงแค่บอกว่าพาร์ติชั่นติดตั้งผ่านอุปกรณ์ "loopback" เสมือน
goldilocks

5

เมื่อคุณใช้dd if=/dev/sdx of=/path/to/image bs=1M, /dev/sdxหมายถึงทั้ง "ดิสก์" เพื่อให้ภาพที่มักจะมีขนาดของการ์ดทั้งหมด

แต่คุณจะต้องใช้dd if=/dev/sdxn ...ที่nเป็นจำนวนพาร์ทิชัน

คุณอาจต้องทำสองครั้ง - หนึ่งครั้งสำหรับ/bootพาร์ติชันและอีกครั้งสำหรับ/พาร์ติชัน

จากนั้นคุณจะต้องสร้างพาร์ติชันบนการ์ดใหม่ที่มีขนาดใหญ่เท่ากับพาร์ติชันดั้งเดิมสองอันเพื่อสร้างเนื้อหากลับไป


3

ใช้สิ่งที่ต้องการแยกส่วน (ตัวแก้ไขพาร์ติชัน) เพื่อย่อขนาดพาร์ติชันหลักให้เล็กลงแล้วใช้เครื่องมือเช่น Clonezilla เพื่อคัดลอกจากพาร์ติชันที่มีขนาดเล็กลงไปยังการ์ดใหม่ของคุณ คุณอาจจะต้องทำสิ่งนี้กับคอมพิวเตอร์เครื่องอื่น


น่าเสียดายที่นี่ไม่ได้ผล ฉันย่อขนาดพาร์ติชันเป็น 2.5 GB ด้วย GParted แต่เมื่อฉันพยายามสร้างภาพจากแท่ง USB มันก็ใหญ่ขึ้น (4.3 GB - แต่ฉันคิดว่ามันต้องการคัดลอกทั้ง 32 GB และหยุดที่ 4.3 GB เนื่องจากข้อ จำกัด ขนาดไฟล์ FAT)
mwld

2
ฉันใช้คำสั่งdd if=/dev/sdx of=/path/to/image bs=1Mจากกระทู้นี้: raspberrypi.stackexchange.com/questions/311/…
mwld

คุณมีความคิดใด ๆ เกี่ยวกับวิธีที่ฉันสามารถคัดลอกพาร์ติชั่นหลักที่มีขนาด 2.5 GB ลงในภาพและยังคงสร้างการ์ด SD ที่สามารถบูต Raspbian ได้จากมัน?
mwld

ขอโทษที่ตอบช้า. ฉันเริ่มต้นด้วยการ์ด SD 4GB สร้างภาพจากนั้นเขียนภาพนั้นเป็น 8GB และการ์ดขนาดใหญ่ขึ้น ฉันไม่ต้องการใช้พาร์ติชันที่ใหญ่กว่าสำหรับทุกอย่างที่ฉันเคยทำ ฉันไม่รู้เครื่องมือที่จะให้คุณสร้างภาพของแต่ละพาร์ติชันบนการ์ด SD
Jerry Gagnon

3
  1. สร้างภาพของการ์ดโดยใช้หนึ่งในวิธีที่กล่าวมาแล้ว - ฉันจะสำรอง Raspberry Pi ได้อย่างไร

  2. ใช้สคริปต์ที่http://sirlagz.net/2013/03/10/script-automatic-rpi-image-downsizer/เพื่อลดขนาดรูปภาพ

  3. คืนค่ารูปภาพที่ลดขนาดลงในการ์ดขนาดเล็กใหม่


ฉันชนในหน้านี้ขณะที่ฉันพยายามบรรลุเป้าหมายเดียวกันเพื่อสำรองข้อมูลภาพราสเบียนของฉัน แต่ฉันไม่ต้องการข้อมูลทั้งการ์ดเฉพาะที่เกี่ยวข้องในการ์ด ตามข้อเสนอแนะข้างต้นฉันกำลังมองหาสคริปต์ที่นี่sirlagz.net/2013/03/10/script-automatic-rpi-image-downsizerแต่ไม่พบ มีใครอัปเดตที่ลิงค์นี้ไหม
shallyverma

ฉันยังคงสามารถเข้าถึงลิงก์และโพสต์ตัวเองเป็นสคริปต์ คัดลอกสคริปต์ลงในไฟล์และตั้งชื่อscript.shให้สร้างไฟล์เรียกใช้โดยใช้chmodและเรียกใช้งาน
Mihir

1

ฉันใช้rsyncเพื่อคัดลอกระบบไฟล์จากดิสก์หนึ่งไปยังอีกในขณะนี้โดยไม่มีอาการสะอึก ข้อดีของการใช้ rsync คือการคัดลอกเนื้อหาของระบบไฟล์แทนที่จะทำสำเนาระดับบล็อกของอุปกรณ์ ผลก็คือมันไม่ได้สนใจขนาดของไดรฟ์เป้าหมายและไดรฟ์ต้นทางตราบใดที่ไดรฟ์เป้าหมายมีพื้นที่เพียงพอสำหรับเก็บข้อมูล

ดังนั้นนี่คือวิธีที่ฉันจะทำ:

  1. สร้างการติดตั้งราสเบียนใหม่บนการ์ด SD ขนาดเล็กที่คุณต้องการ
  2. บูตเข้าสู่การติดตั้งใหม่และขยายระบบไฟล์เพื่อเติมทั้งดิสก์ ปี่ปิด
  3. ตอนนี้เมานต์การ์ดเก่าและใหม่และใช้rsync -avx oldFilesystem newFilesystemเพื่อคัดลอก / เขียนทับระบบไฟล์บนการ์ดใหม่ด้วยระบบไฟล์จากการ์ดเก่า
  4. ในที่สุดให้บู๊ตเข้าสู่ระบบใหม่ของคุณและรันrpi-updateเพื่อให้แน่ใจว่าเฟิร์มแวร์ของคุณสอดคล้องและเป็นปัจจุบัน

หลังจากนี้การ์ดใหม่ของคุณควรติดตั้งระบบ Raspbian ที่ใช้งานได้อย่างสมบูรณ์


ดังนั้นสำหรับวิธีนี้ (ขั้นตอนที่ 3) ฉันต้องการเครื่องอ่านการ์ด SD 2 เครื่องใช่ไหม
Victor Van Hee

มีเครื่องอ่านการ์ด SD สองเครื่องหรืออุปกรณ์ระดับกลาง คุณสามารถซิงค์ระบบไฟล์เก่าไปยังโฟลเดอร์ในฮาร์ดไดรฟ์ของคุณแล้วซิงค์โฟลเดอร์นั้นไปยังการ์ด SD ตัวที่สองหากคุณไม่ต้องการรับเครื่องอ่าน
sdenton4

1

ฉันสร้างเชลล์สคริปต์เพื่อสำรองข้อมูลและกู้คืนข้อมูลทั้งหมดในการ์ด SD ก่อนอื่นจะลบข้อมูลบางส่วน (สอดคล้องกับโครงการของฉัน) และลดขนาดพาร์ติชันให้มีขนาดต่ำสุดเพื่อให้ภาพมีขนาดใหญ่เท่ากับข้อมูลในการ์ด SD นอกจากนี้สคริปต์จะสร้างไฟล์ * .zip ของภาพ หลังจากกู้คืนรูปภาพที่สร้างไปยังการ์ด SD อื่นพาร์ติชันจะถูกขยายเป็นขนาดสูงสุด สคริปต์ใช้คำสั่งที่กล่าวถึงในคำตอบอื่น ๆ เช่นนี้เป็นสคริปต์เชลล์กำปั้นของฉันด้วยขนาดนี้ฉันใช้เวลาหลายชั่วโมงในการสร้างมัน โดยเฉพาะอย่างยิ่งฉันไม่รู้วิธีจัดการค่าส่งคืนของ resize2fs และ fdisk ดังนั้นผู้ใช้ต้องพิมพ์ค่าที่ฉันต้องการ มีแนวคิดใดที่จะแก้ไขได้หรือไม่ ฉันหวังว่าสคริปต์นี้จะช่วยคนอื่น รู้สึกอิสระที่จะแก้ไขและปรับปรุง

"Usage:
    <skriptname> -b <path>                  create backup of SC Card (dev/mmcblk0) to file <path>/JJJJ-MM-DD_HHMM.img
    <skriptname> -r <path>/FILENAME.img     restore an exitsting image (<path>/FILENAME.img) to the SD Card (dev/mmcblk0) 
    <skriptname> -r <path>/FILENAME.zip     unzip and restore an exitsting image (<path>/FILENAME.zip) to the SD Card (dev/mmcblk0)
    <skriptname> -h                         show this hlep

นี่มันคือ:

#!/bin/bash 

# check if the user is root
if (( $EUID != 0 )); then
  echo "This script requires root privileges please run as root"
  exit
fi


while getopts ":b:r:h" opt; do
  case $opt in
    b)
      mode="backup"
      OUTPATH=$OPTARG
      ;;
    r)
      mode="restore"
      DIRFILENAME=$OPTARG
      ;;
    h)
      mode="help"
      ;;
    \?)
      echo "Invalid option: -$OPTARG. Use -h for help" >&2
      exit 1
      ;;
    :)
      echo "Option -$OPTARG requires an argument. Use -h for help" >&2
      exit 1
      ;;
  esac
done
# no option
if [ $OPTIND == 1 ]
then
  echo "$(basename "$0") needs an option! Use -h for help"
  exit 1
fi


myMount(){
  # create mountpoint if not existing
  if [ ! -d /tmp/sd2/ ] ; then
    mkdir /tmp/sd2
  fi

  # mount partition
  mount -v -t ext4 /dev/mmcblk0p2 /tmp/sd2
  err=$?
  if [ $err != 0 ]; then
    echo "mount failed error: $err"
    exit 1
  fi
}

myUmount(){
  cd /home/ # otherwise umount will fail
  # fuser -vm /tmp/sd2/

  # umount partition
  umount -v /tmp/sd2
  err=$?
  if [ $err != 0 ]; then
    echo "umount failed error: $err"
    exit 1
  fi
}

myEnlarge(){
  echo "enlarge partition..."
  # enlarge partition is not posible with fdisk -> delete and recreate it
  (
  echo d # delete partition
  echo 2 # patition number
  echo n # add a new partition
  echo p # primary partition
  echo 2 # partition number
  echo   # first sector (accept default: varies)
  echo   # last sector (accept default: varies)
  echo w # write changes
  ) | fdisk /dev/mmcblk0

  echo "\n check filesystem... "
  e2fsck -f -v -C 0 /dev/mmcblk0p2

  # enlarge filesystem to maxsize
  resize2fs -p /dev/mmcblk0p2
}

case "$mode" in
"help")
  echo "Usage:
    $(basename "$0") -b <path>                  create backup of SC Card (dev/mmcblk0) to file <path>/JJJJ-MM-DD_HHMM.img
    $(basename "$0") -r <path>/FILENAME.img     restore an exitsting image (<path>/FILENAME.img) to the SD Card (dev/mmcblk0) 
    $(basename "$0") -r <path>/FILENAME.zip     unzip and restore an exitsting image (<path>/FILENAME.zip) to the SD Card (dev/mmcblk0)
    $(basename "$0") -h                         show this hlep
--------------------------------
Adrian Zeitler, Germany 2017"
  ;;
"backup")  ####################################### backup ####################################### 
  echo "an image of the SD Card (/dev/mmcblk0) whitch is as smal as possible will be created to $OUTPATH."
  # ------------------  delete some data --------------------

  echo "Do you want to delete tempfiles? [y/n]" 
  read delfiles

  if [ "$delfiles" = "y" ]
    then
      echo "Delete tempfiles..."

      myMount

      # remove some data
      cd /tmp/sd2/home/alarm/
      rm -v -f hagelbeere.db
      rm -v -f HAILcam.log
      rm -v -f HAILcam.log.1
      rm -v -f test.jpg

      myUmount

    elif [ "$delfiles" = "n" ]
      then
    echo "I don't delete anything."
    else
    echo "Sorry, I didn't understand."
    exit 1
  fi


  # --------------------------------------------------------------
  # shrink partition 2 to minimum size

  echo "check file system... "
  e2fsck -f -v -C 0 /dev/mmcblk0p2
  err=$?
  if [ $err != 0 ]; then
    echo "file system check failed, error: $err"
    exit 1
  fi

  echo "shrink filesystem of partition 2 to minimum size..."
  resize2fs -p -M /dev/mmcblk0p2
  err=$?
  if [ $err != 0 ]; then
    echo "resize2fs failed, error: $err"
    exit 1
  fi
  # --> Das Dateisystem auf /dev/mmcblk0p2 ist nun 692365 Blöcke groß.

  echo "Please tell me the new filesystem size displayed above:"
  read size
  # from resize2fs blocksize, fdisk wants sector: sector = block * 8
  size=$(( $size*8 ))

  # shrink partition is not posible with fdisk -> delete and recreate it
  (
  echo d # delete partition
  echo 2 # patition number
  echo n # add a new partition
  echo p # primary partition
  echo 2 # partition number
  echo   # first sector (accept default: varies)
  echo +$size  # last sector
  echo w # write changes
  ) | fdisk /dev/mmcblk0
  err=$?
  if [ $err != 0 ]; then
    echo "fdisk failed, error: $err"
    exit 1
  fi


  # --------------------------------------------------------------

  # fill unused space with zeros
  echo "Do you want to fill unused space with zeros? [y/n]" 
  read fillzeros


  if [ "$fillzeros" = "y" ]
    then
      echo "Copy zeros. This will end up with an error. But this is ok."

      myMount    

      dd if=/dev/zero | pv | dd of=/tmp/sd2/nullen.datei conv=noerror,notrunc,sync bs=10240
      # exits with error -> this is normal

      # dlelete zeros
      rm -v -f /tmp/sd2/nullen.datei
      sync

      myUmount

    elif [ "$fillzeros" = "n" ]
      then
    echo "I don't delete anything."
    else
    echo "Sorry, I didn't understand."
    exit 1
  fi

  # --------------------------------------------------------------

  # find out end of partition
  fdisk -l /dev/mmcblk0
  echo "Please tell me the end of mmcblk0p2 displayed above."
  read count



  DATE=$(date +"%Y-%m-%d_%H%M")
  IMGFILENAME=$DATE.img 
  echo "Do you want to create image with filename $OUTPATH$IMGFILENAME? [y/n]"
  read answer
  if [ "$answer" = "y" ]
  then
    echo "Do you want to create a *.zip file of the created image? [y/n]"
    read zip
    echo "Do you want to enlarge partition 2 to maxsize after image creation? [y/n]"
    read enlarge

    echo "create image..."
    cd $OUTPATH
    # create image with dd, stop at and of partition
    # count=N   copy only N input blocks
    # bs=BYTES  read and write up to BYTES bytes at a time = block size
    # pv    show status
    dd if=/dev/mmcblk0 | pv -s $(( $count*512 )) | dd of=$IMGFILENAME bs=512 count=$count
    err=$?
    if [ $err != 0 ]; then
      echo "dd failed error: $err"
      exit 1
    fi

    # --------------------------------------------------------------
    # create zip file
    # or like this:
    # sudo dd if=/dev/sdX | pv |gzip > /pfad/zur/datei.img.gz
    if [ "$zip" = "y" ]
    then
      echo "create zip file..."
      zip $DATE.zip $IMGFILENAME
    fi
    # --------------------------------------------------------------
  fi

  # --------------------------------------------------------------
  # enlarge partition 2

  if [ "$enlarge" = "y" ]
  then
    myEnlarge
  fi

  ;; #end case mode backup
"restore")  ####################################### restore ####################################### 
  #chek if image exists
  if [[ -s "$DIRFILENAME" ]]
  then
    # check if file is an image or zip file
    if [[ $DIRFILENAME =~ \.img$ ]]
    then
      IMGFILENAME=$(basename "$DIRFILENAME")
    elif [[ $DIRFILENAME =~ \.zip$ ]]
    then
      ZIPFILENAME=$(basename "$DIRFILENAME")
    else
      echo "Not the right file format. I accept *.img and *.zip"
      exit 1
    fi
  else
    echo "Image file does not exist."
    exit 1
  fi
  echo "the file $DIRFILENAME will be restored to the SD Card /dev/mmcblk0"

  #change to the path of the imagefile
  SOURCEPATH=$(dirname "$DIRFILENAME")
  cd $SOURCEPATH


  if [ "$ZIPFILENAME" != "" ]
  then
    echo "unzip file"
    # change file extention form zip zu img
    l=$(( ${#ZIPFILENAME}-3 ))
    IMGFILENAME="${ZIPFILENAME:0:l}img"
    unzip $ZIPFILENAME
  fi

  echo "Do you realy want to restore $SOURCEPATH/$IMGFILENAME to the SD card /dev/mmcblk0? 
  Warning: all data on the device /dev/mmcblk0 will be lost! [y/n]"
  read answer
  if [ "$answer" = "y" ]
  then
    echo "Do you want to enlarge partition 2 to maxsize after restoring? [y/n]"
    read enlarge
    echo "restore image..."
    filesize=$(wc -c <"$IMGFILENAME")
    echo "Filesize = $filesize Byte"
    dd if=$IMGFILENAME | pv -s $filesize | dd of=/dev/mmcblk0 bs=512
    err=$?
    if [ $err != 0 ]; then
      echo "dd failed error: $err"
      exit 1
    fi
  fi

  # --------------------------------------------------------------
  # enlarge partition 2
  if [ "$enlarge" = "y" ]
  then
    myEnlarge
  fi

  ;; #end case mode restore
esac

0

วิธีแก้ปัญหาที่ง่ายที่สุดที่ฉันพบคือทำสำเนาสำรองของการ์ดขนาดใหญ่กว่าเดิมโดยใช้คำสั่ง dd ที่ระบุไว้ด้านบนแล้วเรียกคืนภาพไปยังการ์ดขนาดเล็กโดยใช้บางสิ่งบางอย่างเช่น piwriter dd อาจทำงานได้เช่นกัน ... ไม่แน่ใจ PiWriter ส่งคืนข้อผิดพลาดเนื่องจากไม่มีพื้นที่เหลืออยู่ แต่เนื่องจากรูปภาพไม่ได้มีข้อมูลจริงเกินขนาดการ์ดขนาดเล็กมันจึงตัดส่วนที่ว่างเปล่าออก ฉันไม่แน่ใจว่าสิ่งที่เกี่ยวข้องกับเรื่องนี้คืออะไร ... พาร์ติชันอาจต้องตรวจสอบหรือซ่อมแซม แต่ฉันสามารถตรวจสอบว่ามันทำงานเมื่อฉันใส่ลงใน Pi


1
นี่เป็นคำแนะนำที่อันตรายมากคุณจะไม่มีทางรู้ว่ามีข้อมูลเกินขนาดจริงหรือไม่ เรากำลังมองหาโซลูชั่นที่น่าเชื่อถือและได้รับการพิสูจน์แล้วมากขึ้น
lenik

ฉันมีชีวิตอยู่อย่างอันตรายสิ่งที่ฉันสามารถพูดได้;) ในความร้ายแรงทั้งหมดแม้ว่าฉันจะไม่ได้มีประสบการณ์การทำงานกับ dd หรือแผนที่พาร์ติชันดังนั้นฉันจึงอยู่ในดินแดนที่ไม่ได้จดที่นี่ ฉันอาจจะโชคดีเพราะฉันมีข้อมูลประมาณ 800MB เท่านั้นที่เปลี่ยนจากการ์ด 16GB ไปเป็นการ์ด 8GB มีความเป็นไปได้ไหมที่จะจัดระเบียบข้อมูลก่อนเพื่อให้แน่ใจว่ามีการจัดกลุ่มทั้งหมดที่จุดเริ่มต้นของพาร์ติชันหรือไม่ ดูเหมือนแฮ็ก แต่อาจจะ?
Pooch

ฉันไม่รู้เกี่ยวกับการจัดเรียงข้อมูล แต่คุณอาจปรับขนาดพาร์ติชันของคุณและย้ายพวกเขาไปที่จุดเริ่มต้นของการ์ด SD ดังนั้นพวกเขาจึงครอบครองเฉพาะจุดเริ่มต้น ใช้เวลานานกว่า dd ธรรมดาเล็กน้อย แต่ผลลัพธ์น่าเชื่อถือมากขึ้น
lenik

0

ฉันใช้เวอร์ชั่นเก่าในwin32diskimager-RELEASE-0.1-r15-win32การอ่านภาพมันสร้างภาพขนาด 4GB จากการ์ด SD 8GB และเขียนรูปภาพด้วย win32diskimager เวอร์ชั่นล่าสุด

ฉันใช้เวอร์ชั่นเก่ากว่าเพราะเวอร์ชั่นเก่าจะข้ามทุกข้อผิดพลาด


ไม่มีตัวเลือกในเวอร์ชันใหม่ 0.95 ซึ่งอนุญาตให้คุณทำเช่นเดียวกันนั่นคือข้ามข้อผิดพลาดทุกข้อใช่ไหม น่าเสียดายที่หน้า sourceforgeไม่ปรากฏขึ้นเพื่อแสดงรายการตัวเลือกใด ๆ ที่มี ดูเหมือนว่ามีความเสี่ยงเล็กน้อยในการใช้ซอฟต์แวร์ pre-beta
Greenonline

ฉันไม่ได้รับความอบอุ่นจากการใช้โปรแกรมที่จะข้ามข้อผิดพลาดทั้งหมด
RufusVS
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.