5

I have a workstation that we have set up to sanitize multiple hard drives. I run a script that detects the hard drives and then runs the 'shred' command on each one. The problem is, if any of the hard drives fail (where Ubuntu no longer sees the drive) while 'shred' is running, rather than halting, 'shred' will output into infinity with line after line of this:

shred: /dev/sdd: error writing at offset 103456287104: Input/Output error

I don't see any options for 'shred' to enable it to exit if it encounters errors, and I obviously don't want the script to just run forever with the I/O error. Since 'shred' won't halt on it's own when it encounters this error, something else would have be running in parallel to do some kind of error-checking. In my script, I have the verbose output of 'shred' redirected to a log file, and I actually use that log file to check for successful completion of 'shred' in another part of the script. But I'm not sure how to continuously check that log file while 'shred' is still running.

Anyone have any ideas for how I can accomplish this kind of "parallel error-checking?"

I know the 'wipe' command exits when it detects I/O errors, but for reasons beyond our control, we are limited to using 'shred'. It's kind of frustrating that 'shred' doesn't do the same. It would seem like a no-brainer to have it halt upon error, but.....it doesn't.

This is the "shredding" part of my script:

#!/bin/bash
log=/root/sanilog.txt
## get disks list
drives=$(lsblk -nodeps -n -o name |grep "sd")
for d in $drives; do
     shred -n 3 -v /dev/$d >> $log 2>&1
done

2 Answers2

1

I'm making a script to use shred.

I have the same problem of you, but its possible to do that:

# My device become the variable "$dev"
dev=/dev/sdd

Running Shred using my variable and put the output 2 & 1 (msg and error) in a file, then put & to launch in background

The log file will be shred_sdd.log

${dev:5} means /dev/sdd without the first 5 characters, because '/' is nod good in a file name

shred -fvzn1 "$dev" >"shred_${dev:5}.log" 2>&1 &

So while the pid concerning sdd is running, check word 'error' in the the shred_sdd.log, if yes then write a message and kill the PID, else wait 60 sec before re-checking

while ps aux|grep "shred.${dev}"|grep -v 'grep' >/dev/null; do < "shred_${dev:5}.log" grep -i 'error' >/dev/null if [ $? = 0 ]; then echo "Too much sector defect on the device ${dev}, shred can not continue" PID=$( ps aux|grep "shred.${dev}"|grep -v 'grep'|awk '{print $2}' ) kill -9 "$PID" break
else sleep 60 fi done

You can use a fonction to do the same task with all devices

# Variables of my devices (You can use lsblk, depends your configuration)
devices=$(lsscsi -t | grep disk | grep sas | awk '{print $NF}')

function_shred() {

Put the code here that I wrote previously

}

for dev in $devices; do function_shred & done

Lorenz Keel
  • 9,511
0

set -e at the top of a bash script will cause the script to exit if any commands return a non-zero exit code.

you can also try a EXIT trap to make the script clean up after itself


if don't mind trying an alternative do shred, dd can do a similar job:

dd if=/dev/urandom of=/dev/sdd bs=4096

give it two passes if you're paranoid :)

and ubuntu also have wipe

wipe /dev/sdd

wipe repeatedly overwrites special patterns to the files to be destroyed, using the fsync() call and/or the O_SYNC bit to force disk access. In normal mode, 34 patterns are used (of which 8 are random).

yodog
  • 296