Add HDD device previews and root guards
This commit is contained in:
1 parent
33c4229848
commit
cf53a6bb50
5 files changed
+52
-16
No files matched your search
@@ -20,7 +20,9 @@ Erase, Overwrite. За ATA избира Enhanced Security Erase, ако устр
|
|||||||
потвърждения, като второто е точното име на устройството.
|
потвърждения, като второто е точното име на устройството.
|
||||||
|
|
||||||
**Изтриването е необратимо и при режим за цял диск засяга всички дялове.**
|
**Изтриването е необратимо и при режим за цял диск засяга всички дялове.**
|
||||||
В началото скриптът предупреждава, че работата може да продължи часове, и
|
Преди въпросите за потвърждение скриптът показва наличните block devices,
|
||||||
|
размер, тип, файлов тип и mount points; подаденото устройство е оцветено в
|
||||||
|
червено в терминал. След това скриптът предупреждава, че работата може да продължи часове, и
|
||||||
изисква `yes` за продължаване или `no` за прекратяване. Не изключвай,
|
изисква `yes` за продължаване или `no` за прекратяване. Не изключвай,
|
||||||
рестартирай или приспивай компютъра и не прекъсвай захранването или връзката
|
рестартирай или приспивай компютъра и не прекъсвай захранването или връзката
|
||||||
с диска. За дял следва отделно потвърждение с точния device path; за цял диск
|
с диска. За дял следва отделно потвърждение с точния device path; за цял диск
|
||||||
|
|||||||
+12
-5
@@ -9,12 +9,19 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|||||||
# shellcheck source=lib/common.sh
|
# shellcheck source=lib/common.sh
|
||||||
source "${SCRIPT_DIR}/../lib/common.sh"
|
source "${SCRIPT_DIR}/../lib/common.sh"
|
||||||
|
|
||||||
|
if [[ "$EUID" -ne 0 ]]; then
|
||||||
|
common::log "WARNING: This script must be run as root (for example, with sudo)."
|
||||||
|
common::die "stopping before processing arguments or checking dependencies"
|
||||||
|
fi
|
||||||
|
|
||||||
SCRIPT_HELP=$(cat <<'HELP'
|
SCRIPT_HELP=$(cat <<'HELP'
|
||||||
Usage: sudo ./HDD/erase-storage.sh DEVICE [zero|random]
|
Usage: sudo ./HDD/erase-storage.sh DEVICE [zero|random]
|
||||||
|
|
||||||
For a partition, writes one full pass of zeros (default) or pseudorandom data.
|
For a partition, writes one full pass of zeros (default) or pseudorandom data.
|
||||||
For a whole disk, detects and runs a supported ATA Secure Erase or NVMe Sanitize
|
For a whole disk, detects and runs a supported ATA Secure Erase or NVMe Sanitize
|
||||||
operation. Whole-disk erasure requires two separate confirmations.
|
operation. Whole-disk erasure requires two separate confirmations.
|
||||||
|
Lists available block devices and mount points before continuing, highlighting
|
||||||
|
the selected device in red when run in a terminal.
|
||||||
At startup, asks you to confirm that you can keep the computer and drive
|
At startup, asks you to confirm that you can keep the computer and drive
|
||||||
powered and connected for the hours the operation may take.
|
powered and connected for the hours the operation may take.
|
||||||
|
|
||||||
@@ -53,20 +60,17 @@ case "$FILL_MODE" in
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
common::log "WARNING: Erasing data may take hours. Do not power off, reboot, or suspend the computer, or disconnect power or the drive."
|
for required_command in awk findmnt lsblk readlink swapon date dd sleep; do
|
||||||
common::confirm "Can the computer and drive remain powered and connected until the operation finishes?" || exit 0
|
|
||||||
|
|
||||||
for required_command in findmnt lsblk readlink swapon date dd sleep; do
|
|
||||||
common::require_cmd "$required_command"
|
common::require_cmd "$required_command"
|
||||||
done
|
done
|
||||||
|
|
||||||
[[ "$EUID" -eq 0 ]] || common::die "this script must be run as root (for example, with sudo)"
|
|
||||||
[[ -b "$DEVICE_INPUT" ]] || common::die "$DEVICE_INPUT does not exist or is not a block device"
|
[[ -b "$DEVICE_INPUT" ]] || common::die "$DEVICE_INPUT does not exist or is not a block device"
|
||||||
|
|
||||||
DEVICE="$(readlink -f -- "$DEVICE_INPUT")" || common::die "cannot resolve device path: $DEVICE_INPUT"
|
DEVICE="$(readlink -f -- "$DEVICE_INPUT")" || common::die "cannot resolve device path: $DEVICE_INPUT"
|
||||||
DEVICE_TYPE="$(lsblk -dnro TYPE -- "$DEVICE")" || common::die "cannot determine device type"
|
DEVICE_TYPE="$(lsblk -dnro TYPE -- "$DEVICE")" || common::die "cannot determine device type"
|
||||||
[[ "$DEVICE_TYPE" == "part" || "$DEVICE_TYPE" == "disk" ]] \
|
[[ "$DEVICE_TYPE" == "part" || "$DEVICE_TYPE" == "disk" ]] \
|
||||||
|| common::die "only a partition or a whole disk is accepted (detected: $DEVICE_TYPE)"
|
|| common::die "only a partition or a whole disk is accepted (detected: $DEVICE_TYPE)"
|
||||||
|
common::show_block_devices "$DEVICE" || common::die "cannot list available block devices"
|
||||||
|
|
||||||
ROOT_SOURCE="$(findmnt -n -o SOURCE /)" || common::die "cannot determine the root filesystem device"
|
ROOT_SOURCE="$(findmnt -n -o SOURCE /)" || common::die "cannot determine the root filesystem device"
|
||||||
ROOT_SOURCE="${ROOT_SOURCE%%\[*}"
|
ROOT_SOURCE="${ROOT_SOURCE%%\[*}"
|
||||||
@@ -117,6 +121,9 @@ while IFS= read -r child_device; do
|
|||||||
done <<< "$ACTIVE_SWAP_DEVICES"
|
done <<< "$ACTIVE_SWAP_DEVICES"
|
||||||
done <<< "$DEVICE_TREE"
|
done <<< "$DEVICE_TREE"
|
||||||
|
|
||||||
|
common::log "WARNING: Erasing data may take hours. Do not power off, reboot, or suspend the computer, or disconnect power or the drive."
|
||||||
|
common::confirm "Can the computer and drive remain powered and connected until the operation finishes?" || exit 0
|
||||||
|
|
||||||
if [[ "$DEVICE_TYPE" == "part" ]]; then
|
if [[ "$DEVICE_TYPE" == "part" ]]; then
|
||||||
[[ $# -eq 1 || "$FILL_MODE" == "zero" || "$FILL_MODE" == "random" ]] \
|
[[ $# -eq 1 || "$FILL_MODE" == "zero" || "$FILL_MODE" == "random" ]] \
|
||||||
|| common::die "invalid fill mode; use 'zero' or 'random'"
|
|| common::die "invalid fill mode; use 'zero' or 'random'"
|
||||||
|
|||||||
+4
-2
@@ -16,8 +16,10 @@
|
|||||||
Ако дъщерно устройство не може да се демонтира, скриптът прекратява
|
Ако дъщерно устройство не може да се демонтира, скриптът прекратява
|
||||||
операцията.
|
операцията.
|
||||||
|
|
||||||
В началото скриптът предупреждава, че работата може да продължи часове, и
|
В началото скриптът показва наличните block devices, размер, тип, файлов тип
|
||||||
изисква отговор `yes` за продължаване или `no` за прекратяване. По време на
|
и mount points; подаденият диск е оцветен в червено в терминал. След това
|
||||||
|
предупреждава, че работата може да продължи часове, и изисква отговор `yes`
|
||||||
|
за продължаване или `no` за прекратяване. По време на
|
||||||
целия процес не изключвай компютъра, не го рестартирай/приспивай и не
|
целия процес не изключвай компютъра, не го рестартирай/приспивай и не
|
||||||
прекъсвай захранването или връзката с диска. Преди самия запис има отделно
|
прекъсвай захранването или връзката с диска. Преди самия запис има отделно
|
||||||
потвърждение с `YES`.
|
потвърждение с `YES`.
|
||||||
|
|||||||
+12
-8
@@ -10,12 +10,19 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|||||||
# shellcheck source=lib/common.sh
|
# shellcheck source=lib/common.sh
|
||||||
source "${SCRIPT_DIR}/../lib/common.sh"
|
source "${SCRIPT_DIR}/../lib/common.sh"
|
||||||
|
|
||||||
|
if [[ "$EUID" -ne 0 ]]; then
|
||||||
|
common::log "WARNING: This script must be run as root (for example, with sudo)."
|
||||||
|
common::die "stopping before processing arguments or checking dependencies"
|
||||||
|
fi
|
||||||
|
|
||||||
SCRIPT_HELP=$(cat <<'HELP'
|
SCRIPT_HELP=$(cat <<'HELP'
|
||||||
Usage: sudo ./HDD/repair-hdd.sh DEVICE [zero|null|random]
|
Usage: sudo ./HDD/repair-hdd.sh DEVICE [zero|null|random]
|
||||||
|
|
||||||
Overwrites the selected disk, then runs a SMART extended self-test. This
|
Overwrites the selected disk, then runs a SMART extended self-test. This
|
||||||
destroys all data on DEVICE. Use only with a directly connected SATA disk;
|
destroys all data on DEVICE. Use only with a directly connected SATA disk;
|
||||||
USB adapters may require adding -d sat to the smartctl calls.
|
USB adapters may require adding -d sat to the smartctl calls.
|
||||||
|
Lists available block devices and mount points before continuing, highlighting
|
||||||
|
the selected device in red when run in a terminal.
|
||||||
At startup, asks you to confirm that you can keep the computer and drive
|
At startup, asks you to confirm that you can keep the computer and drive
|
||||||
powered and connected for the hours this operation may take.
|
powered and connected for the hours this operation may take.
|
||||||
|
|
||||||
@@ -57,23 +64,17 @@ case "$FILL_MODE" in
|
|||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
common::log "WARNING: This operation may take hours. Do not power off, reboot, or suspend the computer, or disconnect power or the drive."
|
for required_command in awk findmnt lsblk readlink swapon mkdir date tee smartctl grep umount dd sync sleep head base64; do
|
||||||
common::confirm "Can the computer and drive remain powered and connected until this operation finishes?" || exit 0
|
|
||||||
|
|
||||||
for required_command in findmnt lsblk readlink swapon mkdir date tee smartctl grep umount dd sync sleep head base64; do
|
|
||||||
common::require_cmd "$required_command"
|
common::require_cmd "$required_command"
|
||||||
done
|
done
|
||||||
|
|
||||||
if [[ "$EUID" -ne 0 ]]; then
|
|
||||||
common::die "this script must be run as root (for example, with sudo)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ ! -b "$DEVICE" ]]; then
|
if [[ ! -b "$DEVICE" ]]; then
|
||||||
common::die "$DEVICE does not exist or is not a block device"
|
common::die "$DEVICE does not exist or is not a block device"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Refuse the root filesystem device and any block device it depends on.
|
# Refuse the root filesystem device and any block device it depends on.
|
||||||
TARGET_DEVICE="$(readlink -f -- "$DEVICE")" || common::die "cannot resolve device path: $DEVICE"
|
TARGET_DEVICE="$(readlink -f -- "$DEVICE")" || common::die "cannot resolve device path: $DEVICE"
|
||||||
|
common::show_block_devices "$TARGET_DEVICE" || common::die "cannot list available block devices"
|
||||||
ROOT_SOURCE="$(findmnt -n -o SOURCE /)" || common::die "cannot determine the root filesystem device"
|
ROOT_SOURCE="$(findmnt -n -o SOURCE /)" || common::die "cannot determine the root filesystem device"
|
||||||
ROOT_SOURCE="${ROOT_SOURCE%%\[*}"
|
ROOT_SOURCE="${ROOT_SOURCE%%\[*}"
|
||||||
ROOT_DEVICE="$(readlink -f -- "$ROOT_SOURCE")" || common::die "cannot resolve root device path: $ROOT_SOURCE"
|
ROOT_DEVICE="$(readlink -f -- "$ROOT_SOURCE")" || common::die "cannot resolve root device path: $ROOT_SOURCE"
|
||||||
@@ -100,6 +101,9 @@ while IFS= read -r child_device; do
|
|||||||
done < <(swapon --show --noheadings --raw --output NAME)
|
done < <(swapon --show --noheadings --raw --output NAME)
|
||||||
done <<< "$DEVICE_TREE"
|
done <<< "$DEVICE_TREE"
|
||||||
|
|
||||||
|
common::log "WARNING: This operation may take hours. Do not power off, reboot, or suspend the computer, or disconnect power or the drive."
|
||||||
|
common::confirm "Can the computer and drive remain powered and connected until this operation finishes?" || exit 0
|
||||||
|
|
||||||
if [[ "$FILL_MODE" == "random" ]] && ! command -v openssl >/dev/null 2>&1; then
|
if [[ "$FILL_MODE" == "random" ]] && ! command -v openssl >/dev/null 2>&1; then
|
||||||
common::log "OpenSSL is unavailable; random mode will use /dev/urandom."
|
common::log "OpenSSL is unavailable; random mode will use /dev/urandom."
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -90,3 +90,24 @@ common::require_cmd() {
|
|||||||
common::die "required command '${cmd}' not found on PATH"
|
common::die "required command '${cmd}' not found on PATH"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# common::show_block_devices prints available block devices and highlights
|
||||||
|
# the selected device when output is going to a terminal.
|
||||||
|
common::show_block_devices() {
|
||||||
|
local selected_device="$1"
|
||||||
|
local color=0
|
||||||
|
|
||||||
|
if [[ -t 1 && -z "${NO_COLOR:-}" ]]; then
|
||||||
|
color=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
common::log "Available block devices and mount points (selected device highlighted):"
|
||||||
|
lsblk --list --paths --output PATH,SIZE,TYPE,FSTYPE,MOUNTPOINTS \
|
||||||
|
| awk -v selected="$selected_device" -v color="$color" '
|
||||||
|
NR > 1 && $1 == selected && color {
|
||||||
|
printf "\033[31m%s\033[0m\n", $0
|
||||||
|
next
|
||||||
|
}
|
||||||
|
{ print }
|
||||||
|
'
|
||||||
|
}
|
||||||
Reference in new issue
Block a user