web-dev-qa-db-fra.com

Comment puis-je déchiqueter tous les disques sauf / dev / sda et consigner la sortie dans un fichier?

J'essaie de créer une commande qui prend tous les lecteurs qui ne sont pas sda, les exécute et les sauvegarde dans un fichier journal. Jusqu'ici j'ai

find /dev/ -name "sd?" -not -name "sda" -exec [shred -fvz {} > /home/ben/ProjectsInProgress/ShredLogs/$(hdparm -I {} | grep 'Serial\ Number' |cut -f2- -d:).log 2>&1 &] \;

Comme vous pouvez le constater, j’ai parcouru une bonne distance avec Google, mais maintenant je me suis heurté à quelque chose que je ne sais pas quoi faire, car j’ai obtenu le résultat suivant:

[1] 13097
{}: No such file or directory
]: command not found
[1]+  Exit 1                  find /dev/ -name "sd?" -not -name "sda" -exec [shred -fvz {} > /home/ben/ProjectsInProgress/ShredLogs/$(hdparm -I {} | grep 'Serial\ Number' |cut -f2- -d:).log 2>&1

Quelqu'un a-t-il une suggestion?

De plus, je travaille actuellement sur ce problème mais des suggestions seraient bien. Quand je cours

shred -fvz /dev/sdb > /home/ben/ProjectsInProgress/ShredLogs/$(hdparm -I /dev/sdb | grep 'Serial\ Number' |cut -f2- -d:).log 2>&1

Je reçois une erreur de redirection ambiguë.

4
Ben Stumpf

EDIT: Bien que la réponse initiale vous explique en partie pourquoi votre commande find ne fonctionne pas, la boucle utilisant find ne fonctionnera pas pour les disques durs USB. Faites défiler vers le bas de la réponse pour une meilleure version.

Notez que la journalisation ne fonctionnera pas du tout avec les lecteurs flash USB; hdparmn’est que pour les disques durs.


Votre commande find ne fonctionnera pas. Du tout. Pourquoi?

Il y a quelques problèmes, mais le principal est le suivant: L'option -exec recherche dans l'exemplaire PATH le nom de son premier argument et l'exécute avec tous les autres arguments avec find jusqu'à un point-virgule. Il ne () pas ne passe ses arguments à un shell, ce qui signifie qu’il utilise$(...), redirection, etc ne fonctionnera pas.

Comment réparez-vous ceci? Il y a plusieurs façons.

Le plus évident pourrait être de passer votre commande à un shell:

find . -name testing12345 -exec bash -c '...$(...)... > /path/to/some/file 2>&1' \;

Oui, cela fonctionne, mais dans une expression complexe comportant plusieurs types de citations, s’échapper peut rapidement devenir un cauchemar.

Souvent, le moyen le plus simple consiste à utiliser une boucle. Etant donné que vous avez déjà une commande find qui fonctionne, le moyen le plus simple de le faire est d’extraire les arguments -exec et de les diriger dans une boucle:

find (your find arguments here) -print0 | while IFS= read -r -d $'\0' filename; do
    # process "$filename"
done

IFS= et les options -print0 et -d $'\0' pour find et read permettent d'éviter les problèmes de nouvelles lignes dans les noms de fichier. L'option -r garantit que read ne traite pas les barres obliques inverses dans les noms de fichier.

En combinant cela et les solutions à vos autres problèmes, nous obtenons ceci, qui semble fonctionner:

find /dev/ -name "sd?" -not -name "sda" -print0 | while IFS= read -r -d $'\0' filename; do
    if (hdparm -i "$filename" > /dev/null 2>&1); then
        shred -fvz "$filename" > /home/ben/ProjectsInProgress/ShredLogs/$(hdparm -i "$filename" | grep -o 'SerialNo=\S*' |cut -f2 -d=).log 2>&1 &
    fi
done

Je l'ai seulement testé moi-même avec une instruction echo à la place de shred car je ne veux pas déchiqueter mes disques, alors dites-moi si cela fonctionne.


EDIT: La version find est cassée pour les disques durs USB. Cette version modifiée qui utilise lsblk fonctionne correctement:

lsblk -ld | grep -o '^sd[b-z]' | while read -r filename; do
    filename="/dev/$filename"
    shred -fvz "$filename" > "/home/ben/ProjectsInProgress/ShredLogs/$(hdparm -I "$filename" | grep -o 'Serial Number:\s*\S*' | cut -f2 -d: | sed 's/^\s*//').log" 2>&1 &
done
2
insert_name_here

Ce script doit faire ce que vous voulez. Notez qu'il doit être exécuté en tant que root!

#!/bin/bash
logpath="/home/ben/ProjectsInProgress/ShredLogs"
lsblk -l | grep -o '^sd[b-z] ' | while read f; do
    logfile="$logpath/$(hdparm -i "/dev/$f" | grep -oP "(?<=SerialNo=)\w+")"
    shred -fvz "$f" &> "$logfile"
done

Merci à @ terdon pour cette version améliorée (et, espérons-le, maintenant corrigée).

S'il vous plaît dites-moi si cela fonctionne, je ne suis pas vraiment motivé pour tester le déchiquetage de mes propres disques ...

2
Byte Commander