0

I need to programatically get the Volume Serial Number of a FAT volume (for example, a USB drive or removable SD card) in mac OS. Do you know of any program with which to do it? (Bonus points for a Python API call!)

To clarify, I'm asking for the hyphenated 8-hex-digit number that is displayed by the vol command in DOS:

C:\>vol e:
Volume in Drive E is MYSDCARD
Volume Serial Number is E432-EF79

E432-EF79 is the VSN I'm looking for. It may sometimes be referred to as a UUID, though it's not 128 bits long.

On Mac I can mount the drive, and get its volume name, using commands like df. I can inspect it in DiskUtility, and see things like capacity and device name. But how do I get the VSN?

1

For a FAT32 formatted disk, in Terminal, the following example compound command will output its volume serial number:

var="$(sudo dd if=/dev/diskNs1 skip=67 bs=1 count=4 2>/dev/null | hexdump -e '4/4 "%X"')"; echo "${var:0:${#var}/2}-${var:${#var}/2}"
  • Replace N in /dev/diskNs1 with the correct disk number.
    • You can use the mount command or diskutil list to ascertain the disk number of the target disk.
  • Note that the target disk needs to first be unmounted before running the example compound command.

Assuming the target disk is mounted as /dev/disk6s1, in Terminal use:

diskutil unmountDisk disk6

After the target disk is unmounted, then use:

var="$(sudo dd if=/dev/disk6s1 skip=67 bs=1 count=4 2>/dev/null | hexdump -e '4/4 "%X"')"; echo "${var:0:${#var}/2}-${var:${#var}/2}"

For my test disk, a USB flash drive formatted FAT32, the output was:

18E4-4FA7

I confirmed this with the vol command in Windows and the blkid command in Linux, and the output of vol and blkid matched the output of the example compound command above.


Notes:

With FAT32 volumes, the Volume Serial Number is stored in the Boot Sector at offset 67 (0x43), and is four bytes long.

Interesting Reading: Volume Serial Numbers and Format Date/Time Verification

There may be a way to format the output of the dd command with hexdump to avoid the rest of the compound command, however, I didn't want to take the time to figure it out and chose to use parameter expansion and shell arithmetic instead for the final formatting.

1
  • Wow, this is impressive. I tested it, and it worked for me. I wish my program wouldn't have to have root access and unmount the disk in order to get this info, but that may not be possible. You've given me a way to do it (and proven the results) when I had no way before. – LarsH Dec 11 '20 at 16:34
1

Q: "how do I get the VSN?"

This Wikipedia article indicates the FAT VSN is based on the RTC in the system used to create or format the disk. Interestingly, it's said that Microsoft & IBM created the VSN to keep up with an early innovation by Apple!

As you've suggested, it seems that the the label UUID is used in some systems instead of VSN - e.g. this seems to be the case with the lsblk utility widely used in most Linux/Unix systems. However, macOS (specifically the diskutil tool) uses a "true" 128-bit UUID for FAT volumes. For FAT volumes then, there are two methods for creating a "unique" identifier. Intuitively, it seems that the 128-bit UUID is much more likely to be "unique" than the VSN.

You've indicated your preference for the VSN in your question, and that may be "unique enough" for your application. However, given that there doesn't seem to be any readily available tools for macOS to easily extract the VSN (vol for macOS :), you may wish to consider an alternative:

Step 1: Get the device name

% DEVNM=`diskutil list | grep FAT | grep -o "disk[0-9]s[0-9]"`
% echo $DEVNM
disk4s1

Step 2: Get the UUID (EDITED)

Using macOS' diskutil piped through grep with a regular expression will output the 128-bit UUID:

% diskutil info "$DEVNM" | grep "Volume UUID:" | grep -o '[0-9A-Z]*-[0-9A-Z]*-[0-9A-Z]*-[0-9A-Z]*-[0-9A-Z]*'
74453B21-2067-3766-8A2D-EA0AC27F99A8

Alternatively:

  • You asked about a Python API call:

    • the uuid.py library may be useful generating UUIDs (perhaps for use in Windows?)

    • The Python FAT Reader project may be useful for extracting VSNs from FAT volumes, but it seems to use dd which will (inconveniently) require the volume be unmounted.

  • The article Get FAT Drive Serial Numbers in Unix has a good walk-through & explanation with a CLI for fetching a VSN from several FAT variants. It's similar to another answer here.

  • If the drive is exFAT, you can use this:

    % sudo newfs_exfat -N disk3s1 | grep Volume Serial
    

    Unfortunately, newfs_msdos doesn't have a facility for outputting the VSN.

15
  • 1
    1. The first command in Step 1: Get the device name errors with zsh: command not found: list because you did not include appropriate command substitution. 2. In Step 2: Get the UUID, the Volume UUID: of the diskutil info command is not the same as the Volume Serial Number of a FAT32 formatted drive. -- For my test disk, in Linux, the blkid command outputs e.g. /dev/sdb1: LABEL="DATA" UUID="18E4-4FA7" TYPE="vfat" and in macOS, the Volume UUID: of the diskutil info command outputs e.g. E92BA062-FB92-3473-825C-DF7102F7226E – user3439894 Dec 11 '20 at 13:34
  • 1
    Which parses to E92BA062-F, B92-3, 473-8 and 25C-D with your grep command. So is not really clear how you ended up with 5966-39BF. AFAICT diskutil info does not or does not consistently output the Volume Serial Number of a FAT32 formatted drive. With FAT32 volumes, the Volume Serial Number is stored in the Boot Sector at offset 67 (0x43), and is four bytes long. – user3439894 Dec 11 '20 at 13:34
  • 1
    AFAICT In macOS, it has to be read at the disk level using e.g. dd and then be properly formatted to produce the same results as on Windows or Linux using the vol and blkid commands, respectively. In my testing diskutil info does read the four bytes starting at offset 67 (0x43) in the Boot Sector of my FAT32 formatted USB drive. – user3439894 Dec 11 '20 at 13:34
  • 1
    @Seamus In my testing, the volume UUID produced by diskutil was 09181F6D-2A59-3A51-AC79-B0F0EA862CB8, and parsing it with the regexps you suggested does not produce anything that matches the format of a VSN. In other words, user3439894 is right. – LarsH Dec 11 '20 at 19:58
  • 1
    Seamus, I asked specifically for the VSN -- which "may sometimes be referred to as a UUID, though it's not 128 bits long." In other words, any true, 128-bit UUID is not the VSN, and is not what I need. – LarsH Dec 13 '20 at 2:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .