Send the wrong SCSI command to the wrong device with sg3_utils and you can format a disk you meant only to look at. This guide finds the right device name, runs a read-only inquiry, saves decoded output for later, and turns a non-zero exit status into an actual diagnosis. Allow about 10 minutes if the device is already attached. You need the sg3-utils package and access to a SCSI generic device, usually under /dev/sg*.
This guide is based on sg3_utils 1.46, provided here by Debian package version 1.46-3ubuntu4. The package bundles many separate programs, and their names usually describe the SCSI command they send: sg_inq sends INQUIRY, sg_readcap reads capacity, sg_logs fetches log pages.
Most commands need permission to open the device, so check group membership and the device nodes first:
command -v sg_inq
sg_inq --version
ls -l /dev/sg*
On this release, sg_inq --version prints a utility version string. Device nodes are commonly owned by root:disk; being able to see a node does not mean your account can use it.
sg_scan -i
The -i option asks the scanner to issue INQUIRY and show identifying information. It is a read-only discovery operation, but it still opens each device, so a permission error here means you need an approved group or sudo just to run the discovery itself.
Linux also exposes disk-style names such as /dev/sda and optical names such as /dev/sr0, and the manpage notes that current kernels will normally accept almost any suitable device name for these utilities. The generic name is what you want when you need the SCSI pass-through interface explicitly. Do not guess from the number: map it with discovery first, and note the mapping somewhere.
DEVICE=/dev/sg0
sg_inq "$DEVICE"
Expect vendor, product and revision information when the target accepts INQUIRY; exact lines depend on target and transport. This command does not format, write or start a disk. It can still fail if the device is busy, unavailable, behind a restricted pass-through interface, or simply does not support the requested command.
For a stable, machine-friendly identity page, ask for the device identification VPD page instead:
sg_inq --id "$DEVICE"
Keep that output alongside the host name and device path. A path like /dev/sg0 is assigned by discovery order and can change after reboot; the identifier the device itself returns is a far better basis for an inventory record.
DEVICE=/dev/sg0
sg_inq --hex "$DEVICE" > inquiry.hex
sg_inq --inhex=inquiry.hex "$DEVICE"
--hex writes an ASCII hexadecimal response, and the matching input option tells a utility to decode a saved response rather than fetch a fresh one. For utilities where the input file supplies all response data, the device argument may be ignored, so check that particular utility's own usage message. Treat a captured response as evidence, not as a file to edit casually.
If another program needs raw bytes rather than text, keep that output separate from diagnostic messages:
sg_inq --raw "$DEVICE" > inquiry.bin
file inquiry.bin
Do not open a binary capture in a text editor, and do not redirect raw output straight to a terminal.
sg3_utils returns zero for success and non-zero for failure, and the non-zero value is not a generic shell error: many of them describe SCSI sense conditions directly. Status 2 means the device is not ready, 5 commonly means an illegal request, 9 means an unsupported command, and 33 means a command timeout.
sg_decode_sense --err=2
sg_decode_sense --err=33
On this installation the first command reports the device as not ready, the second a SCSI command timeout. Capture standard error alongside standard output when you're diagnosing a real command:
if ! sg_inq "$DEVICE" > inquiry.txt 2> inquiry.err; then
status=$?
printf 'sg_inq failed with status %s\n' "$status" >&2
sg_decode_sense --err="$status"
sed -n '1,80p' inquiry.err >&2
fi
Watch for a shell trap here: inside if ! command, $? is the status of !, not the original command. For a script that must keep the exact code, run the command first, save $?, then test the saved value.
=, such as --timeout=30; short options normally use a space, such as -t 30.--verbose can be repeated. Extra diagnostics normally go to standard error, so they never corrupt raw output.--maxlen limits the response allocation length. Useful for unusual devices, but an unnecessarily large request can upset faulty or fragile USB storage.0x100 or 100h, and documented multipliers such as 2k. Check the individual utility before relying on a suffix.--old or SG3_UTILS_OLD_OPTS exists purely for compatibility.Safety boundary: INQUIRY, scans and log reads are generally observational. Other programs in the package can write blocks, alter modes, start or stop media, download firmware, or format a device outright. Treat sg_dd, sg_format, sg_modes with select write actions, and any firmware tool as a change operation. Confirm the device by its stable identity, check that utility's own manpage, and use --dry-run where that utility documents it; a dry run is not universal and is not a substitute for an offline backup.
Do not reach for sudo as a reflex. Elevation only changes access permission; it does not make a guessed device safe. If a write command has already changed state, stop and follow the target manufacturer's recovery procedure rather than improvising a second write or format command.
sg_scan -i or another trusted inventory source.sg_inq returned identity data for the intended device./dev/sgN.sg_decode_sense before you retried anything.