bash: สคริปต์แก้ Boot record ของ NTFS
update 2556-12-03
ลองใช้สคริปต์กับพาร์ติชั่นที่ขนาดไม่เท่ากันแล้วปรากฎว่าใช้ไม่ได้ เพราะ NTFS เก็บข้อมูลหลายอย่างมากกว่าแค่จุดเริ่มต้นและขนาด (ดูที่ NTFS Partition Boot Sector)
วิธีที่ได้ผลกว่าคือ ฟอร์แมตไดร์ฟไว้ก่อน -> เก็บ boot sector ไว้ 72 ไบต์ -> ทำ ntfsclone -> เอา boot recort ที่เก็บไว้มาเขียนทับ
ตัวอย่างเช่น จะคัดลอก ไดร์ฟ /dev/sda1 ไปยัง /dev/sdb1 ขั้นตอนจะเป็นดังนี้
$ sudo mkfs.ntfs -f /dev/sdb1 $ sudo dd if=/dev/sdb1 of=sdb1.img bs=72 count=1 $ sudo ntfsclone -O /dev/sdb1 /dev/sda1 $ sudo dd if=sdb1.img of=/dev/sdb1
*** สคริปต์ด้านล่างนี้ ล้าสมัยแล้ว ***
แก้ปัญหาเวลาใช้ ntfsclone ในการ restore พาร์ติชั่น NTFS มาลงในฮาร์ดดิสก์ลูกใหม่ ซึ่งจุดเริ่มต้นและขนาดอาจไม่เท่าของเดิม
วิธีการคือใช้ข้อมูลจากตาราง Master Boot Record ปัจจุบัน มาเขียนทับ boot record ของพาร์ติชั่น NTFS ที่ต้องการ โดยใช้เชลล์สคริปต์
$ vi ntfs_fix_boot_sector.sh
#!/bin/bash function usage() { cat <<EOF Fix NTFS boot record: Usage: $0 DEVICE Example: $0 /dev/sda1 EOF exit 1 } if [ ! "$1" ]; then usage fi PART=$1 if [ ! -b "$PART" ]; then echo -e "$PART not found. Exit.\n" usage fi BSF="`echo $PART | tr '/' '_'`.img" BSFB=${BSF}.bak BSFD="${BSF}_`date +%F`.bak" function reverse_byte () { #reverse_byte HEXSTR local S=$1 #HEXSTR local B local C while [ "$S" ]; do B=${S:(-2)} S=${S:0:-2} C="${C}\\x${B}" done echo $C } function replace_byte () { #replace_byte OFFSET LENGTH NUMBER local O=$1 #OFFSET local L=$2 #LENGTH local N=$3 #NUMBER let NL=${L}*2 XN=`printf "%0${NL}x" $N` RXN=`reverse_byte $XN` #echo "printf $RXN | dd of=$BSF bs=1 seek=$O count=$L conv=notrunc" printf $RXN | sudo dd of=$BSF bs=1 seek=$O count=$L conv=notrunc > /dev/null 2>&1 } sudo dd if=$PART of=$BSF bs=512 count=1 > /dev/null 2>&1 TMP="/tmp/$0_${RANDOM}.txt" HDD=$PART while [ "`echo ${HDD:(-1)} | tr '0123456789' ' '`" == " " ]; do HDD=${HDD:0:-1} done sudo fdisk -l $HDD > $TMP if ! cat $TMP | grep $PART | grep NTFS > /dev/null 2>&1; then echo -e "$PART is not NTFS partition. Exit.\n" sudo rm $TMP sudo rm $BSF usage fi if [ ! -f "$BSFB" ]; then cp $BSF $BSFB else cp $BSF $BSFD fi echo "Fixing $PART ..." HEADS=`cat $TMP | grep 'sectors/track' | cut -d, -f1 | cut -d\ -f1` SECTORS=`cat $TMP | grep 'sectors/track' | cut -d, -f2 | cut -d\ -f2` START=`cat $TMP | grep "${PART} " | awk -F' ' '{ print $2 }'` END=`cat $TMP | grep "${PART} " | awk -F' ' '{ print $4 }'` if [ "$START" == "*" ]; then START=`cat $TMP | grep "${PART} " | awk -F' ' '{ print $3 }'` END=`cat $TMP | grep "${PART} " | awk -F' ' '{ print $4 }'` fi let LENGTH=$END-$START OFFSET_HEADS=26 OFFSET_SECTORS=24 OFFSET_START=28 OFFSET_LENGTH=40 LEN_HEADS=1 LEN_SECTORS=1 LEN_START=4 LEN_LENGTH=4 for i in HEADS SECTORS START LENGTH; do A="OFFSET_${i}" B="LEN_${i}" replace_byte ${!A} ${!B} ${!i} done echo "Fix with heads=$HEADS, sectors/track=$SECTORS, start=$START, length=$LENGTH" sudo dd if=$BSF of=$PART > /dev/null 2>&1 sudo rm $TMP cat <<EOF Command used: sudo dd if=$BSF of=$PART Revert with command: sudo dd if=$BSFB of=$PART EOF
ตัวอย่าง สมมุติว่าพาร์ติชั่นที่ต้องการเป็น /dev/sda1 คำสั่งคือ
$ ntfs_fix_boot_record.sh /dev/sda1
ได้ผลลัพธ์คือ
Fixing /dev/sda1 ... Fix with heads=255, sectors/track=63, start=2048, length=62914559 Command used: sudo dd if=_dev_sda1.img of=/dev/sda1 Revert with command: sudo dd if=_dev_sda1.img.bak of=/dev/sda1
ที่มา:
- Printer-friendly version
- Log in or register to post comments
- 7397 reads
Recent comments