Skip to content

Instantly share code, notes, and snippets.

@lboulard
Last active January 20, 2019 08:55
Show Gist options
  • Select an option

  • Save lboulard/0afdf6ccfaf2ac8635fce6a8967c9e7f to your computer and use it in GitHub Desktop.

Select an option

Save lboulard/0afdf6ccfaf2ac8635fce6a8967c9e7f to your computer and use it in GitHub Desktop.
Zeroed free space of vfat filesystem
#!/bin/sh
set -eu
usage() {
printf "usage: %s <filesystem>\n\n" "$(basename "$0")"
}
if [ $# != 1 ]; then usage >&2; exit 1; fi
fs="${1%/}"
test -d "$fs" || {
echo "** ERROR: \"$fs\" does not exists"
return 1
}
debug=${debug:-}
size=$((1024 * $(df --output=avail "$fs" | tail -n 1)))
split=$((2 * 1024 * 1024 * 1024))
# just for quick test
if [ -n "$debug" ]; then
size=$((1024 * 1024 * 10))
split=$((1 * 1024 * 1024))
fi
# Pretty print a number
ppn() {
local n s sufx
n="$1"
sufx=""
s="$n$sufx"
while [ ${#s} -gt 5 ] && [ "$sufx" != "Yi" ]; do
case "$sufx" in
(Zi) sufx="Yi" ;;
(Ei) sufx="Zi" ;;
(Pi) sufx="Ei" ;;
(Ti) sufx="Pi" ;;
(Gi) sufx="Ti" ;;
(Mi) sufx="Gi" ;;
(Ki) sufx="Mi" ;;
("") sufx="Ki" ;;
esac
n=$((n / 1024))
s="$n$sufx"
done
echo "$s"
}
zero() {
dd if=/dev/zero bs=1M count="$(((size + 1024*1024 - 1) /(1024*1024)))" status=none
}
fseq() {
local offset i remain
i=0
remain="$size"
for offset in $(seq 0 "$split" "$size"); do
if [ "$remain" -lt "$split" ]; then
echo "$i" "$offset" "$remain"
else
echo "$i" "$offset" "$split"
fi
i=$((i+1))
remain=$((remain - split))
test "$remain" -eq "0" && break
done
}
wipe() {
local wd i offset n filename count
wd="$1"
exec 3<&0
exec <&-
fseq | while read -r i offset n; do
filename="$(printf "%s/_wipe%04d" "$wd" "$i")"
if [ -n "$debug" ]; then
printf>&2 "# segment %d/%d (%s, %s remaining)\n" \
"$((i + 1))" "$segments" "$(ppn "$n")" "$(ppn $((size - offset)))"
printf>&2 "# Creating %s\n" "$filename"
fi
count=$((n /1024 /64))
dd <&3 "of=$filename" oflag=sync,noatime status=none ibs=64K obs=1M "count=$count"
done
}
target="$fs/_wipe"
test -d "$target" && rm -fr "$target"
test -d "$target" && {
echo "** ERROR: \"$target\" already exists and is not a directory"
exit 1
}
mkdir "$target"
if [ -n "$debug" ]; then
segments=$(( (size + split - 1) / split ))
printf>&2 "# %d segments will be created\n" "$segments"
fi
zero | pv -s "$size" -B 64K | wipe "$target"
[ -n "$debug" ] && ls -lh "$target"
rm -vfr "$target"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment