SG_RAW(8)
π SG_RAW(8) Β· SG3_UTILS π
β¨ NAME β¨
sg_raw - send arbitrary SCSI or NVMe command to a device π
π¦ SYNOPSIS π¦
sg_raw [--binary] [--cmdfile=CF] [--cmdset=CS] [--enumerate] [--help]
[--infile=IFILE] [--nosense] [--nvm] [--outfile=OFILE] [--raw]
[--readonly] [--request=RLEN] [--scan=FO,LO] [--send=SLEN] [--skip=KLEN]
[--timeout=SECS] [--verbose] [--version] DEVICE [CDB0 CDB1 ...]
πΈ DESCRIPTION πΈ
okay so sg_raw lets you send an arbitrary SCSI command (anywhere from 6 to 256 bytes) to a DEVICE π
there might be no data transfer at all, or you can read data from a file and send it over, or you can receive data from the device and then display it or write it to a file. no cap, that's a lot of options bestie π
if the pass through supports it, you can even send bidirectional commands, the ones that carry data going to the DEVICE and data coming back from it, all in one go π₯
the SCSI command is between 6 and 256 bytes long, and each command byte is written in plain hex (00..FF) with no prefix or suffix. you can hand the command over on the command line or through the --cmdfile=CF option. check the EXAMPLES section below if you want to see it in action β¨
the commands travel through a generic SCSI interface that's been built for several operating systems, including Linux, FreeBSD and Windows. iconic, right? π
experimental support has also landed for sending NVMe Admin and NVM commands to the DEVICE π§ since every NVMe command is 64 bytes long, it's way easier to use --cmdfile=CF than to type all 64 bytes on the command line. see the section on NVME below for the tea β
the tool uses a heuristic based on command length to decide whether your command is SCSI or NVMe. if it guesses wrong, you can override it with the --cmdset=CS option π
π OPTIONS π
ngl the options are the main event here, so buckle up π arguments to long options are mandatory for short options as well, so if the long form needs a value, the short form needs one too. the options are arranged in alphabetical order based on the long option name β¨
-b,--binaryβ dump data in binary form, even when you're writing to stdout π-c,--cmdfile=CFβ CF is the name of a file that holds the command to run. without this option, the command has to be typed on the command line, after the options and the DEVICE π-C,--cmdset=CSβ CS picks which command set to use (SCSI or NVMe) π₯ the default,0, lets the command-length heuristic decide. use1to force the SCSI command set, or2to force the NVMe command set π-h,--helpβ shows usage info and exits π«Ά-i,--infile=IFILEβ reads binary data from IFILE instead of stdin π this is ignored unless--sendis specified. if used, that data becomes the command's "data-out" buffer π-n,--nosenseβ hides SCSI Sense information π-N,--nvmβ when sending NVMe commands, the Admin command set is assumed by default. if you want the NVM command set instead (like the Read and Write user data commands), you need to give this option π§-o,--outfile=OFILEβ writes the data received from the DEVICE to OFILE π¦ that data is the command's "data-in" buffer, and it gets written in binary. by default the data is dumped in hex to stdout. if OFILE is-, the data is dumped in binary to stdout instead. this option is ignored unless--requestis specified πΈ-w,--rawβ treats CF (the command file) as containing binary. the default assumption is ASCII hexadecimal, so use this if your file is raw bytes π€-R,--readonlyβ opens the DEVICE read-only π without this option, it opens read-write π-r,--request=RLENβ you're expecting up to RLEN bytes of data back from the DEVICE β¨ you can add aksuffix to count in kilobytes (1024 bytes) instead of bytes. RLEN is decimal unless it has a leading0xor a trailinghπ’
β οΈ bestie, if RLEN is too small (smaller than what the cdb asks for in its "allocation length" field, and/or smaller than what the DEVICE tries to send back), the HBA driver may complain π going bigger than needed should cause no problems at all. most SCSI "data-in" commands return a data block that has a length in its early bytes, which is what the DEVICE would "like" to send back if the cdb's "allocation length" field is big enough. in practice, the DEVICE never returns more bytes than the "allocation length" field in the cdb says π
-Q,--scan=FO,LOβ scans a range of opcodes (the first byte of each command) π the first opcode is FO (decimal unless it has a0xprefix orhsuffix), and the last one is LO. the max value of LO is255. the rest of the SCSI/NVMe command stays exactly as you supplied it at invocation π
π¨ warning, this one can be dangerous!! sending somewhat arbitrary commands to a device can have unexpected results π it's recommended to use this with--cmdset=CSwhere CS is1or2, so the command set can't switch around mid-scan.
-s,--send=SLENβ reads SLEN bytes of data, either from stdin or a file, and sends them to the DEVICE π€ on the SCSI transport, SLEN becomes the length in bytes of the "data-out" buffer. SLEN is decimal unless it has a leading0xor a trailinghπ
it's on you to make sure the "data-out" length implied or stated in the cdb matches SLEN π«Ά heads up that some common SCSI commands, like WRITE(10), have a "transfer length" field measured in logical blocks (usually 512 or 4096 bytes long), not bytes π§
-k,--skip=KLENβ skips the first KLEN bytes of the input file or stream βοΈ this is ignored unless--sendis specified. if you give--sendbut not this option, zero bytes get skipped π₯-t,--timeout=SECSβ waits up to SECS seconds for the command to finish (default:20) β±οΈ if a command times out, the operating system may start by aborting it, and if that doesn't work it may try to reset the device π¬ the alternate long form is--tmo=SECSπ¦-v,--verboseβ cranks up the verbosity π’ you can use it more than once π-V,--versionβ shows version and license info, then exits πΈ
β¨ EXAMPLES β¨
These examples, apart from the last one, use Linux device names π§. For suitable device names in other supported Operating Systems, check out the sg3_utils(8) man page π.
sg_raw /dev/scd0 1b 00 00 00 02 00
Eject the medium in CD drive /dev/scd0 πΏβ¨
sg_raw -r 1k /dev/sg0 12 00 00 00 60 00
Perform an INQUIRY on /dev/sg0 and dump the response data (up to 1024 bytes) to stdout π¨οΈπΈ
sg_raw -s 512 -i i512.bin /dev/sda 3b 02 00 00 00 00 00 02 00 00
Okay so writing 512 bytes to a sector on a disk is lowkey dangerous π so we're not doing that. Instead this one reads i512.bin (assumed to be 512 bytes long) and uses the SCSI WRITE BUFFER command to send it to the "data" buffer (that's mode 2). This is a safe operation π«Άπ
sg_raw -r 512 -o o512.bin /dev/sda 3c 02 00 00 00 00 00 02 00 00
This one uses the SCSI READ BUFFER command to read 512 bytes from the "data" buffer (aka mode 2) and then writes it to the o512.bin file π. If you pair it with the previous example and both commands work, then cmp i512.bin o512.bin should show a match π₯π
sg_raw --infile=urandom.bin --send=512 --request=512 --outfile=out.bin
"/dev/bsg/7:0:0:0" 53 00 00 00 00 00 00 00 01 00
This is a bidirectional XDWRITEREAD(10) command being sent through a Linux bsg device π¦. Data gets read from urandom.bin and sent to the device (data-out), while the resulting data (data-in) lands in the out.bin file. Also note that the length of both is 512 bytes, which lines up with the transfer length of 1 (block) in the cdb (aka the second last byte) π§. The urandom.bin file can be made like this:
dd if=/dev/urandom bs=512 count=1 of=urandom.bin
sg_raw.exe PhysicalDrive1 a1 0c 0e 00 00 00 00 00 00 e0 00 00
This one is from Windows πͺ and shows an ATA STANDBY IMMEDIATE command being sent to PhysicalDrive1. That ATA command is wrapped inside the SCSI ATA PASS-THROUGH(12) command (check out the SAT or SAT-2 standard at https://www.t10.org) π. Notice that STANDBY IMMEDIATE doesn't send or receive any extra data, but if it fails, sense data should be returned and displayed π
For NVME examples, peep the files in this package's inhex directory that start with nvme_, such as inhex/nvme_identify_ctl.hex π
β¨ EXIT STATUS β¨
The exit status of sg_raw is 0 when it's successful π
. Otherwise, check out the sg3_utils(8) man page π
β¨ AUTHOR β¨
Written by Ingo van Lil π«Ά
β¨ REPORTING BUGS β¨
Report bugs to <inguin at gmx dot de> or to <dgilbert at interlog dot com> ππ
β¨ COPYRIGHT β¨
Copyright Β© 2001-2023 Ingo van Lil This software is distributed under the GPL version 2. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE πβοΈ
β¨ SEE ALSO β¨
sg_inq, sg_vpd, sg3_utils (sg3_utils), plscsi πβ¨
Thanks for hanging with me through the whole SG_RAW(8) glow-up, bestie! πΈπ Source: sg3_utils 1.48, dated May 2023. Stay iconic, stay curious, and don't forget to hydrate π π¦
π¦ where this page comes from
- alpine 3.24: sg3_utils-doc 1.48-r0 Β· BSD-2-Clause AND GPL-2.0-or-later
- arch rolling: sg3_utils 1.49-1 Β· GPL-2.0-or-later AND BSD-2-Clause
- centos-stream 10: sg3_utils 1.48-11.el10 Β· GPL-2.0-or-later AND BSD-2-Clause
- debian trixie: sg3-utils 1.48-3~deb13u1
- fedora 43: sg3_utils 1.48-10.fc43 Β· GPL-2.0-or-later AND BSD-2-Clause
- fedora 43: sg3_utils 1.48-6.fc43 Β· GPL-2.0-or-later AND BSD-2-Clause
- fedora 44: sg3_utils 1.48-10.fc44 Β· GPL-2.0-or-later AND BSD-2-Clause
- fedora 44: sg3_utils 1.48-8.fc44 Β· GPL-2.0-or-later AND BSD-2-Clause
- nixos 26.05: sg3_utils 1.48
- nixpkgs unstable: sg3_utils 1.49
- ubuntu questing: sg3-utils 1.48-2ubuntu1
- ubuntu resolute: sg3-utils 1.48-3ubuntu3
- ubuntu resolute: sg3-utils 1.48-3ubuntu3.2
- ubuntu stonking: sg3-utils 1.48-3ubuntu5
- π girlified by anthropic/claude-haiku-5.5 on : a language model's rewrite of the original, under its terms