【问题标题】:How to get hard disk serial number using Python如何使用 Python 获取硬盘序列号
【发布时间】:2011-05-10 18:15:29
【问题描述】:

如何在Linux 上使用Python 获取hard disk 驱动器的serial number?

我想使用 Python 模块来执行此操作,而不是运行外部程序,例如 hdparm。也许使用fcntl 模块?

【问题讨论】:

    标签: python linux hard-drive serial-number fcntl


    【解决方案1】:

    Linux

    正如您所建议的,fcntl 是在 Linux 上执行此操作的方法。您要翻译的 C 代码如下所示:

    static struct hd_driveid hd;
    int fd;
    
    if ((fd = open("/dev/hda", O_RDONLY | O_NONBLOCK)) < 0) {
        printf("ERROR opening /dev/hda\n");
        exit(1);
    }
    
    if (!ioctl(fd, HDIO_GET_IDENTITY, &hd)) {
        printf("%.20s\n", hd.serial_no);
    } else if (errno == -ENOMSG) {
        printf("No serial number available\n");
    } else {
        perror("ERROR: HDIO_GET_IDENTITY");
        exit(1);
    }
    

    在 Ubuntu 9.10 上翻译成 Python,有点像这样:

    import sys, os, fcntl, struct
    
    if os.geteuid() >  0:
        print("ERROR: Must be root to use")
        sys.exit(1)
    
    with open(sys.argv[1], "rb") as fd:
        # tediously derived from the monster struct defined in <hdreg.h>
        # see comment at end of file to verify
        hd_driveid_format_str = "@ 10H 20s 3H 8s 40s 2B H 2B H 4B 6H 2B I 36H I Q 152H"
        # Also from <hdreg.h>
        HDIO_GET_IDENTITY = 0x030d
        # How big a buffer do we need?
        sizeof_hd_driveid = struct.calcsize(hd_driveid_format_str)
    
        # ensure our format string is the correct size
        # 512 is extracted using sizeof(struct hd_id) in the c code
        assert sizeof_hd_driveid == 512 
    
        # Call native function
        buf = fcntl.ioctl(fd, HDIO_GET_IDENTITY, " " * sizeof_hd_driveid)
        fields = struct.unpack(hd_driveid_format_str, buf)
        serial_no = fields[10].strip()
        model = fields[15].strip()
        print("Hard Disk Model: %s" % model)
        print("  Serial Number: %s" % serial_no)
    
    
    ## For documentation purposes, this is the struct copied from <hdreg.h>
    # struct hd_driveid {
    #   unsigned short  config;     /* lots of obsolete bit flags */
    #   unsigned short  cyls;       /* Obsolete, "physical" cyls */
    #   unsigned short  reserved2;  /* reserved (word 2) */
    #   unsigned short  heads;      /* Obsolete, "physical" heads */
    #   unsigned short  track_bytes;    /* unformatted bytes per track */
    #   unsigned short  sector_bytes;   /* unformatted bytes per sector */
    #   unsigned short  sectors;    /* Obsolete, "physical" sectors per track */
    #   unsigned short  vendor0;    /* vendor unique */
    #   unsigned short  vendor1;    /* vendor unique */
    #   unsigned short  vendor2;    /* Retired vendor unique */
    #   unsigned char   serial_no[20];  /* 0 = not_specified */
    #   unsigned short  buf_type;   /* Retired */
    #   unsigned short  buf_size;   /* Retired, 512 byte increments
    #                    * 0 = not_specified
    #                    */
    #   unsigned short  ecc_bytes;  /* for r/w long cmds; 0 = not_specified */
    #   unsigned char   fw_rev[8];  /* 0 = not_specified */
    #   unsigned char   model[40];  /* 0 = not_specified */
    #   unsigned char   max_multsect;   /* 0=not_implemented */
    #   unsigned char   vendor3;    /* vendor unique */
    #   unsigned short  dword_io;   /* 0=not_implemented; 1=implemented */
    #   unsigned char   vendor4;    /* vendor unique */
    #   unsigned char   capability; /* (upper byte of word 49)
    #                    *  3:  IORDYsup
    #                    *  2:  IORDYsw
    #                    *  1:  LBA
    #                    *  0:  DMA
    #                    */
    #   unsigned short  reserved50; /* reserved (word 50) */
    #   unsigned char   vendor5;    /* Obsolete, vendor unique */
    #   unsigned char   tPIO;       /* Obsolete, 0=slow, 1=medium, 2=fast */
    #   unsigned char   vendor6;    /* Obsolete, vendor unique */
    #   unsigned char   tDMA;       /* Obsolete, 0=slow, 1=medium, 2=fast */
    #   unsigned short  field_valid;    /* (word 53)
    #                    *  2:  ultra_ok    word  88
    #                    *  1:  eide_ok     words 64-70
    #                    *  0:  cur_ok      words 54-58
    #                    */
    #   unsigned short  cur_cyls;   /* Obsolete, logical cylinders */
    #   unsigned short  cur_heads;  /* Obsolete, l heads */
    #   unsigned short  cur_sectors;    /* Obsolete, l sectors per track */
    #   unsigned short  cur_capacity0;  /* Obsolete, l total sectors on drive */
    #   unsigned short  cur_capacity1;  /* Obsolete, (2 words, misaligned int)     */
    #   unsigned char   multsect;   /* current multiple sector count */
    #   unsigned char   multsect_valid; /* when (bit0==1) multsect is ok */
    #   unsigned int    lba_capacity;   /* Obsolete, total number of sectors */
    #   unsigned short  dma_1word;  /* Obsolete, single-word dma info */
    #   unsigned short  dma_mword;  /* multiple-word dma info */
    #   unsigned short  eide_pio_modes; /* bits 0:mode3 1:mode4 */
    #   unsigned short  eide_dma_min;   /* min mword dma cycle time (ns) */
    #   unsigned short  eide_dma_time;  /* recommended mword dma cycle time (ns) */
    #   unsigned short  eide_pio;       /* min cycle time (ns), no IORDY  */
    #   unsigned short  eide_pio_iordy; /* min cycle time (ns), with IORDY */
    #   unsigned short  words69_70[2];  /* reserved words 69-70
    #                    * future command overlap and queuing
    #                    */
    #   unsigned short  words71_74[4];  /* reserved words 71-74
    #                    * for IDENTIFY PACKET DEVICE command
    #                    */
    #   unsigned short  queue_depth;    /* (word 75)
    #                    * 15:5 reserved
    #                    *  4:0 Maximum queue depth -1
    #                    */
    #   unsigned short  words76_79[4];  /* reserved words 76-79 */
    #   unsigned short  major_rev_num;  /* (word 80) */
    #   unsigned short  minor_rev_num;  /* (word 81) */
    #   unsigned short  command_set_1;  /* (word 82) supported
    #                    * 15:  Obsolete
    #                    * 14:  NOP command
    #                    * 13:  READ_BUFFER
    #                    * 12:  WRITE_BUFFER
    #                    * 11:  Obsolete
    #                    * 10:  Host Protected Area
    #                    *  9:  DEVICE Reset
    #                    *  8:  SERVICE Interrupt
    #                    *  7:  Release Interrupt
    #                    *  6:  look-ahead
    #                    *  5:  write cache
    #                    *  4:  PACKET Command
    #                    *  3:  Power Management Feature Set
    #                    *  2:  Removable Feature Set
    #                    *  1:  Security Feature Set
    #                    *  0:  SMART Feature Set
    #                    */
    #   unsigned short  command_set_2;  /* (word 83)
    #                    * 15:  Shall be ZERO
    #                    * 14:  Shall be ONE
    #                    * 13:  FLUSH CACHE EXT
    #                    * 12:  FLUSH CACHE
    #                    * 11:  Device Configuration Overlay
    #                    * 10:  48-bit Address Feature Set
    #                    *  9:  Automatic Acoustic Management
    #                    *  8:  SET MAX security
    #                    *  7:  reserved 1407DT PARTIES
    #                    *  6:  SetF sub-command Power-Up
    #                    *  5:  Power-Up in Standby Feature Set
    #                    *  4:  Removable Media Notification
    #                    *  3:  APM Feature Set
    #                    *  2:  CFA Feature Set
    #                    *  1:  READ/WRITE DMA QUEUED
    #                    *  0:  Download MicroCode
    #                    */
    #   unsigned short  cfsse;      /* (word 84)
    #                    * cmd set-feature supported extensions
    #                    * 15:  Shall be ZERO
    #                    * 14:  Shall be ONE
    #                    * 13:6 reserved
    #                    *  5:  General Purpose Logging
    #                    *  4:  Streaming Feature Set
    #                    *  3:  Media Card Pass Through
    #                    *  2:  Media Serial Number Valid
    #                    *  1:  SMART selt-test supported
    #                    *  0:  SMART error logging
    #                    */
    #   unsigned short  cfs_enable_1;   /* (word 85)
    #                    * command set-feature enabled
    #                    * 15:  Obsolete
    #                    * 14:  NOP command
    #                    * 13:  READ_BUFFER
    #                    * 12:  WRITE_BUFFER
    #                    * 11:  Obsolete
    #                    * 10:  Host Protected Area
    #                    *  9:  DEVICE Reset
    #                    *  8:  SERVICE Interrupt
    #                    *  7:  Release Interrupt
    #                    *  6:  look-ahead
    #                    *  5:  write cache
    #                    *  4:  PACKET Command
    #                    *  3:  Power Management Feature Set
    #                    *  2:  Removable Feature Set
    #                    *  1:  Security Feature Set
    #                    *  0:  SMART Feature Set
    #                    */
    #   unsigned short  cfs_enable_2;   /* (word 86)
    #                    * command set-feature enabled
    #                    * 15:  Shall be ZERO
    #                    * 14:  Shall be ONE
    #                    * 13:  FLUSH CACHE EXT
    #                    * 12:  FLUSH CACHE
    #                    * 11:  Device Configuration Overlay
    #                    * 10:  48-bit Address Feature Set
    #                    *  9:  Automatic Acoustic Management
    #                    *  8:  SET MAX security
    #                    *  7:  reserved 1407DT PARTIES
    #                    *  6:  SetF sub-command Power-Up
    #                    *  5:  Power-Up in Standby Feature Set
    #                    *  4:  Removable Media Notification
    #                    *  3:  APM Feature Set
    #                    *  2:  CFA Feature Set
    #                    *  1:  READ/WRITE DMA QUEUED
    #                    *  0:  Download MicroCode
    #                    */
    #   unsigned short  csf_default;    /* (word 87)
    #                    * command set-feature default
    #                    * 15:  Shall be ZERO
    #                    * 14:  Shall be ONE
    #                    * 13:6 reserved
    #                    *  5:  General Purpose Logging enabled
    #                    *  4:  Valid CONFIGURE STREAM executed
    #                    *  3:  Media Card Pass Through enabled
    #                    *  2:  Media Serial Number Valid
    #                    *  1:  SMART selt-test supported
    #                    *  0:  SMART error logging
    #                    */
    #   unsigned short  dma_ultra;  /* (word 88) */
    #   unsigned short  trseuc;     /* time required for security erase */
    #   unsigned short  trsEuc;     /* time required for enhanced erase */
    #   unsigned short  CurAPMvalues;   /* current APM values */
    #   unsigned short  mprc;       /* master password revision code */
    #   unsigned short  hw_config;  /* hardware config (word 93)
    #                    * 15:  Shall be ZERO
    #                    * 14:  Shall be ONE
    #                    * 13:
    #                    * 12:
    #                    * 11:
    #                    * 10:
    #                    *  9:
    #                    *  8:
    #                    *  7:
    #                    *  6:
    #                    *  5:
    #                    *  4:
    #                    *  3:
    #                    *  2:
    #                    *  1:
    #                    *  0:  Shall be ONE
    #                    */
    #   unsigned short  acoustic;   /* (word 94)
    #                    * 15:8 Vendor's recommended value
    #                    *  7:0 current value
    #                    */
    #   unsigned short  msrqs;      /* min stream request size */
    #   unsigned short  sxfert;     /* stream transfer time */
    #   unsigned short  sal;        /* stream access latency */
    #   unsigned int    spg;        /* stream performance granularity */
    #   unsigned long long lba_capacity_2;/* 48-bit total number of sectors */
    #   unsigned short  words104_125[22];/* reserved words 104-125 */
    #   unsigned short  last_lun;   /* (word 126) */
    #   unsigned short  word127;    /* (word 127) Feature Set
    #                    * Removable Media Notification
    #                    * 15:2 reserved
    #                    *  1:0 00 = not supported
    #                    *  01 = supported
    #                    *  10 = reserved
    #                    *  11 = reserved
    #                    */
    #   unsigned short  dlf;        /* (word 128)
    #                    * device lock function
    #                    * 15:9 reserved
    #                    *  8   security level 1:max 0:high
    #                    *  7:6 reserved
    #                    *  5   enhanced erase
    #                    *  4   expire
    #                    *  3   frozen
    #                    *  2   locked
    #                    *  1   en/disabled
    #                    *  0   capability
    #                    */
    #   unsigned short  csfo;       /*  (word 129)
    #                    * current set features options
    #                    * 15:4 reserved
    #                    *  3:  auto reassign
    #                    *  2:  reverting
    #                    *  1:  read-look-ahead
    #                    *  0:  write cache
    #                    */
    #   unsigned short  words130_155[26];/* reserved vendor words 130-155 */
    #   unsigned short  word156;    /* reserved vendor word 156 */
    #   unsigned short  words157_159[3];/* reserved vendor words 157-159 */
    #   unsigned short  cfa_power;  /* (word 160) CFA Power Mode
    #                    * 15 word 160 supported
    #                    * 14 reserved
    #                    * 13
    #                    * 12
    #                    * 11:0
    #                    */
    #   unsigned short  words161_175[15];/* Reserved for CFA */
    #   unsigned short  words176_205[30];/* Current Media Serial Number */
    #   unsigned short  words206_254[49];/* reserved words 206-254 */
    #   unsigned short  integrity_word; /* (word 255)
    #                    * 15:8 Checksum
    #                    *  7:0 Signature
    #                    */
    # };
    

    抱歉,我认为将原始 C 结构作为注释包含在内很有用。另外,我对fcntl 和struct 模块都很陌生,所以我可能正在做一些单一的事情。无论如何,从命令行运行(使用 root privelidges)它看起来像这样(我已经编辑了我的确切序列以保护隐私):

    fmark@fmark-laptop:~/Desktop/hdserial$ sudo python hd.py "/dev/sda"
    Hard Disk Model: FUJITSU MHV2080BH PL
      Serial Number: NW--------
    

    这是怎么回事?

    为了能够理解这里发生了什么,你需要查看原始C程序中的#include &lt;linux/hdreg.h&gt;。这包括导入HDIO_GET_IDENTITY 常量和struct hd_driveid。我已经将结构体作为注释复制到了上面的python源代码中,这里不再赘述。要了解 HDIO_GET_IDENTITY 发生了什么,请用 grep 查找它的源代码(在 Ubuntu 上,它位于 /usr/include/linux/hdreg.h。你应该会找到类似这样的内容:

     #define HDIO_GET_IDENTITY       0x030d  /* get IDE identification info */
    

    因此,您会发现HDIO_GET_IDENTITY 只是一个常量,它告诉 fcntl 您有兴趣获取 HD 信息。您会注意到,相同的值(0x030d 是十六进制表示法的整数)被分配给 Python 代码中的变量。

    窗口

    我现在意识到您对 Linux 很感兴趣,但我将把它留在这里以备后用。下面将获取Windows上的硬盘序列号(需要安装wmi package):

    import wmi
    c = wmi.WMI()
    for item in c.Win32_PhysicalMedia():
        print item
    

    【讨论】:

    • 太棒了,这很好用。我们想在启动到救援环境的系统上获取序列号,但“hdparm -i”不起作用,所以我们正在尝试这个 Python 代码。
    • 要获得实际序列号的 windows 必须阅读 item.wmi_property('SerialNumber').value
    • 这种方式不支持SCSI的磁盘类型,会报错:HDIO_GET_IDENTITY failed: Invalid argument
    【解决方案2】:

    拿一把螺丝刀打开盒子;-)

    如果您在 Windows 上,这可能会解决问题

    import win32api
    print win32api.GetVolumeInformation("C:\\")
    

    为此,您需要 Windows 的 Mark Hammond 模块 http://python.net/crew/mhammond/

    【讨论】:

    • 这将返回卷序列号,而不是 HDD 序列号。有用,但不同。
    • 我知道 Python 自带电池,但我不知道它有螺丝刀!
    【解决方案3】:

    在 Windows 上,您也可以使用内置的subprocess 获取它!

    import subprocess
    
    serials = subprocess.check_output('wmic diskdrive get SerialNumber').decode().split('\n')[1:]
    serials = [s.strip() for s in serials if s.strip()]
    

    如果您还想要其他信息,例如索引和制造商:

    import subprocess
    
    serials = subprocess.check_output('wmic diskdrive get Index, SerialNumber, Manufacturer').decode().split('\n')[1:]
    

    有关可用属性的列表,请查看this documentation。

    【讨论】:

      【解决方案4】:

      窗口

      def get_serial_number_of_physical_disk(drive_letter='C:'):
          import wmi
          
          c = wmi.WMI()
          logical_disk = c.Win32_LogicalDisk(Caption=drive_letter)[0]
          partition = logical_disk.associators()[1]
          physical_disc = partition.associators()[0]
          return physical_disc.SerialNumber
      

      例如:

      get_serial_number_of_physical_disk(os.getenv('SystemDrive'))
      

      将为您提供包含逻辑系统驱动器的磁盘序列号。

      【讨论】:

      • 谢谢!效果很好,只需要用圆括号写os.getenv('SystemDrive') :)
      • 已修复。感谢您提供信息。
      猜你喜欢
      • 1970-01-01
      • 2010-11-24
      • 2014-12-31
      • 2011-05-04
      • 2010-12-06
      • 2016-06-10
      • 2019-03-27
      • 2014-01-11
      • 2011-10-20
      相关资源
      最近更新 更多