Quantcast
Channel: User Kamil Maciorowski - Super User
Viewing all articles
Browse latest Browse all 649

Answer by Kamil Maciorowski for How to write to last 4 bytes of disk via CLI? Like using dd, optional

$
0
0

script3 fails with bs=4

It does not what you want because dd seek=, when given just a number, uses bs as the unit; but your calculation uses blockdev --getsz that counts 512-byte sectors, so it only works with bs=512, unless you recalculate.

To work with bytes, you don't need to recalculate. Get the size of the disk in bytes with blockdev --getsize64 in the first place. Decrement the value by 4, glue B to the end and use it with seek= of recent enough GNU dd. The B postfix informs GNU dd that the unit of this seek= is one byte (regardless of what bs is).

disk=sdXdisk_size=$(sudo blockdev --getsize64 "/dev/$disk") \&& sudo dd if=/dev/urandom of="/dev/$disk" bs=4 count=1 iflag=fullblock \           seek="$((disk_size-4))B"

I think your GNU dd is not recent enough for the above snippet to work. You need seek=… oflag=seek_bytes. In the recent GNU dd this flag is obsolescent. It should still work, but users should prefer the syntax used in the above snippet. You have no choice, use the below.

disk=sdXdisk_size=$(sudo blockdev --getsize64 "/dev/$disk") \&& sudo dd if=/dev/urandom of="/dev/$disk" bs=4 count=1 iflag=fullblock \           seek="$((disk_size-4))" oflag=seek_bytes

Notes:

  • iflag=fullblock because of the possibility of partial reads. In this particular case you want to write until the end of the disk, so you don't really need count=, dd will stop writing at no space left on device (but note it will report non-zero exit status); and if you drop count= then partial writes (if any) won't break anything, so you can as well drop iflag=fullblock. I did not drop them because in general (e.g. when writing to the middle of the disk) you will need them.

  • seek=…B and oflag=seek_bytes are GNU extensions. iflag=fullblock is a new addition to the POSIX standard (in 2024 when I'm writing this; for now with the wrong spelling though, bug report: here). When in doubt, you can always use bs=1 and recalculate count=. Then seek= without B will count bytes (even without oflag=seek_bytes) and there will be no need for iflag=fullblock. With bs=1 the tool will be slower than with bs=512, but this is negligible when writing just 4 bytes.

  • Do not embed $(sudo blockdev …) in the line with dd, do not run dd unconditionally. In the snippet I used &&, so if sudo blockdev … fails then dd will not run. In our particular case an empty value of $disk_size will result in seek=-4B and dd will complain, but in general you may want to do something like seek="$((var+4))B" and then empty $var may be disastrous.

  • The shell arithmetic in Bash does not work well with arbitrarily large integers (compare this question). Disk manufacturers introduce larger and larger disks, but Bash in your Kubuntu can handle integers of this magnitude. Still be aware that in general the shell arithmetic is limited and it does not catch overflows. Example:

    a=111111111111111111111111111111  # stored as stringecho "$a"                         # retrieved as stringecho "$((a))"                     # trivially used in arithmetic expansionecho "$?"

Viewing all articles
Browse latest Browse all 649

Trending Articles