こんにちは、現在単一のコマンドでドライブの配置を一括消去するためにXenialサーバーの1つでこのスクリプトを実行すると問題が発生しました。まず、すべてのドライブがlsblkに表示されるので問題ありません。sudo dd if=/dev/zero of=/dev/<insert drive path> bs=64KB status=progress
複数のタブで実行すると個別に消去されますが、最近は次のエラーに関連する問題が発生しました。
dd: writing to '/dev/sdb'$'\n''sdc'$'\n''sdd': No space left on device
1+0 records in
0+0 records out
0 bytes copied, 0.000280477 s, 0.0kB/s
この問題の原因は何ですか?以下にコードを残しました。ありがとう
#!/bin/bash
erasure=
RAIDFILE="/tmp/raiddrives"
sudo rm "$RAIDFILE"
echo "Drive Wiper 1.3"
echo "Waiting for Disks to initilise"
sleep 30s # Waiting for the HDDs and SSDs to power up.
sudo /opt/MegaRAID/storcli/storcli64 /c0 set alarm=off
sudo /opt/MegaRAID/storcli/storcli64 /c0 show | grep -E ^[[:digit:]]+:[[:digit:]] >> $RAIDFILE
while read LINE; do
declare -a slotinfo
IFS=' ' read -r -a slotinfo <<< "$LINE"
if [ "${slotinfo[2]}" == "UBad" ] && [ "${slotinfo[3]}" == "-" ]; then
IFS=':' read -r -a driveid <<< "${slotinfo[0]}"
sudo /opt/MegaRAID/storcli/storcli64 /c0/e"${driveid[0]}"/s"${driveid[1]}" set good
echo "${slotinfo[0]} has been set to good "
if [ "${slotinfo[2]}" == "UGood" ] && [ "${slotinfo[3]}" == "F" ]; then
sudo /opt/MegaRAID/storcli/storcli64 /c0/fall delete
echo "Deleted foreign RAID config on ${slotinfo[0]} "
fi
if [ "${slotinfo[2]}" == "UGood" ]; then
sudo /opt/MegaRAID/storcli/storcli64 /c0 add vd r0 drives="${slotinfo[0]}"
echo "${slotinfo[0]} available for erasure"
fi
done < "$RAIDFILE"
echo 'Available drive(s) to be wiped' #print a list of the unmounted drives only
declare -a drivevar
drivevar=$(lsblk | awk {'print $1'} | grep '^sd' | grep -v 'sda\|sdb') #removed nvme in live version
echo $drivevar
read -p "Confirm erasure of drives, or to amend list (Y/N/A): " erasure #confirm disk erasure
erasure=${erasure^^} #capitalise erasure
yesnocheck=0 #checking if the user enters a yes or no command.
while [[ yesnocheck -eq 0 ]]; do
case "$erasure" in
Y|YES)
yesnocheck=1
: handle 'yes' cases #dont need any special actions to happen for yes or no cases
;;
N|NO)
yesnocheck=1
: handle 'no' cases
;;
A|AMEND)
unset drivevar 1>&2 #will loop error, and constantly ask for a yes no answer until it receives one.
declare -a drivevar
read -p "Confirm which drives to erase e.g.sda (each seperated by a space)" drivevar
read -p "Confirm erasure of drives, or to amend list (Y/N/A): " erasure
erasure=${erasure^^}
;;
*)
printf '%s\n' "Not a valid selection" 1>&2 #will loop error, and constantly ask for a yes no answer until it receives one.
read -p "Confirm erasure of drives, or to amend list (Y/N/A): " erasure
erasure=${erasure^^}
;;
esac
done
if [ "$erasure" = "Y" -o "$erasure" = "YES" ] ; #or inside a statement
then
{ for i in "${drivevar[@]}"; #getting the results from the drivevar array
do
sudo dd if=/dev/zero of=/dev/"$i" bs=64KB status=progress & #Parrallell Wiping process, wait allows the process to be cancelled although the process is slower.
done
wait
}
elif [ "$erasure" = "N" -o "$erasure" = "NO" ] ;
then
printf '%s\n' 'Operation Aborted!'
else
echo "Ooooops!" #something has gone wrong somewhere, this shouldnt show.
fi
答え1
配列として宣言しdrivevar
ますが、単一要素文字列として使用します。
たとえば、drivevar=$(lsblk...)
配列の最初の(0番目)要素に出力を割り当て、echo $drivevar
同じ要素を出力します。しかし、あなたはそれを配列として使用しません。スペースで区切られた項目のリストを含む文字列として使用します。
これは、繰り返しようとすると、for i in "${drivevar[@]}"
すべての結果が最初の(唯一の)要素にあることを意味します。
おそらく、次の形式の配列割り当てを使用する必要がありますvar=(element element…)
。
drivevar=( $(lsblk …) ) # Assignment
echo "drivevar=( ${drivevar[@]} )" # Debug line, I assume
ああ。元のエラーが発生したファイルを削除する必要があります。ファイル名に改行文字が含まれているため、またはをls
使用すると奇妙に見えることがありますrm
。rm -i
削除前の確認を要求するために使用されます。
rm -i /dev/sdb*sdc*sdd*
ただし、割り当て式は次のように単純化できます。
lsblk | awk {'print $1'} | grep '^sd' | grep -v 'sda\|sdb'
awk | grep
アンチパターンを避けるために、このようなもの
lsblk -dn -o NAME | awk '/^sd[^ab]/'