[svlug] Need a shell/bash loop over each partition and execute dd && rm

Seth David Schoen schoen at loyalty.org
Mon Aug 1 22:08:41 PDT 2011


Rick Moen writes:

> Quoting John Sokol (john.sokol at gmail.com):
> 
> > Make sure the list of partitions looks correct.
> 
> If you'll pardon brief kibbitzing, here's a very minor refinement to your
> script, to exclude various abstract or odd Linux filesystems, in
> addition to the df header line with the word 'Available' in it:
> 
> #!/bin/bash
> for h in $( `df | egrep -v 'Available|tmpfs|udev|ramfs|romfs|cramfs|debugfs' | \
> awk '{print $NF}'`   );do
>    echo "Cleaning partition $h"
>    sudo dd if=/dev/zero of=$hzerofile && sudo rm $hzerofile
> done
> 
> Only the udev and tmpfs ones are likely to be common problems, but 
> I threw in the others just in case.  

I found a way to generalize this further based on the particular set
of filesystems known to the system you're running on: you can replace
the for loop with

for h in $(df $(cat /proc/filesystems | awk '!/^nodev/ {print "-t", $1}') | awk '!/Available/ {print $NF}'); do

Other cautions:

I think $hzerofile should read $h/zerofile.

I discovered by accident that this doesn't work if one of your mount
points contains a space in its name (e.g., "/media/500 GB filesystem"
or "/media/It was a non-Unix user who created this volume label").
This is most likely to happen if you have an automounted that mounts
things on subdirectories of /media based on their volume labels. :-)

There's also a problem if you have a super-long device node name that
causes wrapping, like if you have an encrypted filesystem mounted from
something like:

/dev/mapper/udisks-luks-uuid-12345678-9abc-def0-fedc-ba9876543210-uid1007

which is totally possible on a modern system using udev and LUKS. :-)
In that case your df output will put the device name and the rest of
the data on two separate lines (!), or at least that's what I saw with
GNU coreutils 8.5, even if I made my terminal width extremely large.
I was able to get rid of this particular problem by using df -P.

These problems seem to result basically from the tension between df's
desire to give human-readable output and our desire to parse its output
by machine.  I think I had success dealing with each of them with this
version:

df -P $(cat /proc/filesystems | awk '!/^nodev/ {print "-t", $1}') \
 | grep -v 'Available' | grep '  ' | sed 's:^.* [^/]*/:/:' \
 | while read h; do
    echo "Cleaning partition $h"
    [ -d "$h" ] && sudo dd if=/dev/zero of="$h"/zerofile && \
      sudo rm "$h"/zerofile
done

But because of that tension, it wouldn't be surprising to find another
case where the output of df is different from what we expect in yet
another way.

I haven't tested this but I also fear that the exit code of the dd
command (if it completely fills the partition) will indicate error
rather than success, in which case we won't manage to remove the
zerofile at all (because the rm command thinks that the dd command
failed ... which it did, in a sense).  In that case maybe remove
the file unconditionally:

df -P $(cat /proc/filesystems | awk '!/^nodev/ {print "-t", $1}') \
 | grep -v 'Available' | grep '  ' | sed 's:^.* [^/]*/:/:' \
 | while read h; do
    echo "Cleaning partition $h"
    [ -d "$h" ] && sudo dd if=/dev/zero of="$h"/zerofile
    [ -f "$h"/zerofile ] && sudo rm -f "$h"/zerofile
done

-- 
Seth David Schoen <schoen at loyalty.org>      |  No haiku patents
     http://www.loyalty.org/~schoen/        |  means I've no incentive to
  FD9A6AA28193A9F03D4BF4ADC11B36DC9C7DD150  |        -- Don Marti




More information about the svlug mailing list