A storage vendor's spec sheet claims support for a command, and sg_opcodes lets you ask the device itself rather than trust the marketing. You will finish with a repeatable way to list which commands it supports, inspect one operation code, and look up a command name without touching a device. The examples use sg_opcodes from sg3-utils 1.46-3ubuntu4, whose installed utility reports version 0.69 20210319.
sg3-utils package, and a readable SCSI generic or block device.Start with ordinary, read-only checks. They do not need elevated privileges:
$ command -v sg_opcodes
/usr/bin/sg_opcodes
$ dpkg-query -W -f='${Package} ${Version}\n' sg3-utils
sg3-utils 1.46-3ubuntu4
$ sg_opcodes --version
Version string: 0.69 20210319
The preferred syntax uses long options. The manpage also documents an older option style, but the newer form makes the meaning of an option clearer. Do not mix an old-style assumption about hexadecimal values with the newer syntax: in the preferred form, opcode and service-action values are decimal unless prefixed with 0x or suffixed with h.
Checkpoint: If command -v finds nothing, install or enable the distribution package through your normal change process. Do not copy an unverified binary into /usr/local/bin just to make the example run.
Replace /dev/sdX with the device you have positively identified. A block device such as /dev/sda is supported by modern Linux kernels; an /dev/sgN generic device is also appropriate when you need to target the SCSI generic node explicitly.
$ DEVICE=/dev/sdX
$ sg_opcodes "$DEVICE"
VENDOR PRODUCT REVISION
... device inquiry summary ...
Opcode Service Action CDB Size Command Name
... supported commands ...
The exact vendor strings and command rows depend on the target. By default the utility performs an INQUIRY first, prints a summary, then sends REPORT SUPPORTED OPERATION CODES. The returned list is sorted numerically by opcode and then service action unless you request another order.
If the device refuses the request, first check that DEVICE names the intended target and that your account can read it. Retry with sudo only when the error is a permissions error:
$ sudo sg_opcodes "$DEVICE"
This is an ordinary query, not a repair command. A SCSI target can legally reject REPORT SUPPORTED OPERATION CODES, and a rejection does not prove the device is absent or damaged.
Use --opcode when the full list is too noisy or when you need the device's answer for one command. The value below is an example only:
$ sg_opcodes --opcode=0x93 "$DEVICE"
Opcode=0x93
Command_name: Write same(16)
Command supported [conforming to SCSI standard]
Usage data: ...
The response is device-specific, so treat the output as evidence rather than as a promise that every command can safely be issued. An opcode may have service actions. Give one explicitly when you need to distinguish it:
$ sg_opcodes --opcode=0x9b,0xa "$DEVICE"
These values are parsed as hexadecimal because they use the 0x prefix. The opcode range is 0 through 255, and a service action can range from 0 through 65535. Use --opcode=OP without a service action for a command that has one, and the utility assumes service action zero, which is not the same request as omitting a service action for a command that has none.
--enumerate is useful while reading a trace or a SCSI specification. It ignores DEVICE, so this is a read-only local lookup:
$ sg_opcodes --enumerate --opcode=0x9b,0xa
SCSI command:
Read buffer(16), read data from echo buffer
Omit the values and they default to opcode zero, peripheral device type zero and no service action:
$ sg_opcodes --enumerate
SCSI command:
Test Unit Ready
When a name depends on the peripheral device type, add --pdt. This changes the lookup context; it does not query or alter a device:
$ sg_opcodes --enumerate --pdt=0 --opcode=0x12
The utility's exit status is zero on success. An unknown or unsupported combination can produce an error, so keep the output and status together when using this in a script.
Use --tmf to send REPORT SUPPORTED TASK MANAGEMENT FUNCTIONS instead of listing operation codes:
$ sg_opcodes --tmf --no-inquiry "$DEVICE"
Task Management Functions supported by device:
Abort task
Abort task set
Clear ACA
Clear task set
Logical unit reset
Query task
The exact functions vary by device. In this mode, options such as --opcode, --sa, --alpha and --unsorted are ignored. --no-inquiry suppresses the preliminary inquiry summary; it does not suppress the task-management report itself.
Warning: do not confuse querying supported task management functions with invoking one. sg_opcodes --tmf reports capabilities only. Issuing a task-management function through another tool can disrupt I/O, so keep that work outside this read-only check and use an approved maintenance procedure.
--alpha sorts the command list by name.--unsorted keeps the order supplied by the device.--compact combines opcode and service action and omits the CDB size, which helps prevent long command names wrapping in a terminal.--mask adds the CDB mask. A one marks a bit position that may be set; a zero marks one that must not be set.--mlu adds the multiple-logical-units indication when the response provides it.--hex writes the response as ASCII hexadecimal.Reserve --raw for a program that explicitly expects binary data. It writes the response to standard output, so piping it to a terminal can produce unreadable output. Capture it deliberately:
$ sg_opcodes --raw --no-inquiry "$DEVICE" > sg-opcodes-response.bin
$ wc -c sg-opcodes-response.bin
The file is a diagnostic artefact, not a configuration file. Remove it through your normal data-retention process when it is no longer needed. Do not feed raw output to a text parser and assume displayed bytes are a decoded command list.
For a useful record, keep the command, utility version, device path, exit status and output together:
$ sg_opcodes --compact --no-inquiry "$DEVICE" | tee sg-opcodes.txt
$ status=${PIPESTATUS[0]}
$ printf 'sg_opcodes exit status: %s\n' "$status"
$ test "$status" -eq 0
The device path can be unstable across reboots, especially when several similar disks are present. Before saving a report, confirm the target with your normal udev or storage inventory tools. Never select a disk from a copied example because its name happens to match your own.
sg3-utils and sg_opcodes.--enumerate when no device was available.--tmf only reports task-management support; it does not invoke a task-management function.--raw output as binary and checked the command's exit status.