我正在尝试制作一个命令,该命令将获取所有非 sda 驱动器并在其上运行 shred,并将输出转储到日志文件。到目前为止,我已经
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 &] \;
正如你所看到的,我已经通过谷歌搜索取得了相当大的进展,但现在我遇到了一些我不知道该怎么做的事情,因为我得到的输出是
[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
有人有建议吗?
另外,我目前正在解决这个问题,但建议会很好。当我运行
shred -fvz /dev/sdb > /home/ben/ProjectsInProgress/ShredLogs/$(hdparm -I /dev/sdb | grep 'Serial\ Number' |cut -f2- -d:).log 2>&1
我收到一个模糊的重定向错误。
答案1
find
编辑:虽然原始答案告诉了您命令不起作用的部分原因,但循环使用find
不适用于 USB HDD。滚动到答案底部以获取更好的版本。
请注意,日志记录功能无法与 USB 闪存驱动器配合使用;hdparm
仅适用于 HDD。
你的find
命令不起作用。完全不起作用。为什么?
有几个问题,但主要问题是:该-exec
选项在中查找PATH
具有其第一个参数名称的可执行文件,并使用find
最多分号的任何其他参数执行它。确实如此不是将其参数传递给 shell,这意味着使用 $(...)
、重定向等将不起作用。
如何解决这个问题?有几种方法。
最明显的可能是将你的命令传递给 shell:
find . -name testing12345 -exec bash -c '...$(...)... > /path/to/some/file 2>&1' \;
是的,这是可行的,但是在带有多种引号类型的复杂表达式中,转义很快就会变成一场噩梦。
通常,使用循环是最简单的方法。由于您已经有一个有效的find
命令,因此最简单的方法是-exec
从中取出参数并将其放入循环中:
find (your find arguments here) -print0 | while IFS= read -r -d $'\0' filename; do
# process "$filename"
done
IFS=
以及-print0
和-d $'\0'
选项可find
避免read
文件名中出现换行符的问题。该-r
选项可确保read
不处理文件名中的反斜杠。
结合这一点并解决您的其他问题,我们得到了这个似乎有效的方法:
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
由于我不想粉碎我的磁盘,echo
所以我自己只用一个语句进行了测试,所以如果它有效,请告诉我。shred
编辑:此find
版本不适用于 USB HDD。此修改版本使用以下功能lsblk
可正常运行:
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
此脚本应该可以执行您想要的操作。请注意,它必须以 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
谢谢 @特登提供此改进的(希望现在已修复)版本。
请告诉我它是否有效,我并没有真正积极地测试粉碎我自己的磁盘......