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 needcount=
,dd
will stop writing atno space left on device
(but note it will report non-zero exit status); and if you dropcount=
then partial writes (if any) won't break anything, so you can as well dropiflag=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
andoflag=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 usebs=1
and recalculatecount=
. Thenseek=
withoutB
will count bytes (even withoutoflag=seek_bytes
) and there will be no need foriflag=fullblock
. Withbs=1
the tool will be slower than withbs=512
, but this is negligible when writing just 4 bytes.Do not embed
$(sudo blockdev …)
in the line withdd
, do not rundd
unconditionally. In the snippet I used&&
, so ifsudo blockdev …
fails thendd
will not run. In our particular case an empty value of$disk_size
will result inseek=-4B
anddd
will complain, but in general you may want to do something likeseek="$((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 "$?"