为啥我不能在 python 中调用 HDIO_GETGEO?

Posted

技术标签:

【中文标题】为啥我不能在 python 中调用 HDIO_GETGEO?【英文标题】:Why can't I in python call HDIO_GETGEO?为什么我不能在 python 中调用 HDIO_GETGEO? 【发布时间】:2010-06-27 07:31:25 【问题描述】:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
########## THIS NOW WORKS! ##########

UNSUITABLE_ENVIRONMENT_ERROR = \ 
    "This program requires at least Python 2.6 and Linux"

import sys 
import struct
import os
from array import array

# +++ Check environment
try:
    import platform # Introduced in Python 2.3
except ImportError:
    print >>sys.stderr, UNSUITABLE_ENVIRONMENT_ERROR
if platform.system() != "Linux":
    print >>sys.stderr, UNSUITABLE_ENVIRONMENT_ERROR
if platform.python_version_tuple()[:2] < (2, 6): 
    print >>sys.stderr, UNSUITABLE_ENVIRONMENT_ERROR

# --- Check environment

HDIO_GETGEO = 0x301 # Linux
import fcntl

def get_disk_geometry(fd):
    geometry = array('c',"XXXXXXXX")
    fcntl.ioctl(fd, HDIO_GETGEO, geometry, True)
    heads, sectors, cylinders, start = \ 
        struct.unpack("BBHL",geometry.tostring())
    return  'heads' : heads, 'cylinders': cylinders, 'sectors': sectors, "start": start 

from pprint import pprint
fd=os.open("/dev/sdb", os.O_RDWR)
pprint(get_disk_geometry(fd))

【问题讨论】:

是的,为什么这段代码不工作,一个工作的例子会膨胀:D TypeError: ioctl 需要文件或文件描述符、整数和可选的整数或缓冲区参数未捕获的异常。进入事后调试运行 'cont' 或 'step' 将重新启动程序 > /home/rob/ricedisk(25)get_disk_geometry() -> fcntl.ioctl(fd, HDIO_GETGEO, geometry, True) (Pdb) p HDIO_GETGEO 769 ( pdb) p type(HDIO_GETGEO) (Pdb) p type(fd) 把它放在你的问题中 或者告诉我把 /dev/sdb 放到 /sys/firmware/edd 下的正确位置也可以。 【参考方案1】:

似乎没有人能告诉我为什么你不能这样做,但你可以用 ctypes 做到这一点,所以这并不重要。

#!/usr/bin/env python
from ctypes import *
import os
from pprint import pprint

libc = CDLL("libc.so.6")
HDIO_GETGEO = 0x301 # Linux

class HDGeometry(Structure):
    _fields_ = (("heads", c_ubyte),
                ("sectors", c_ubyte),
                ("cylinders", c_ushort),
                ("start", c_ulong))

    def __repr__(self):
        return """Heads: %s, Sectors %s, Cylinders %s, Start %s""" % (
                self.heads, self.sectors, self.cylinders, self.start)

def get_disk_geometry(fd):
    """ Returns the heads, sectors, cylinders and start of disk as rerpoted by
    Bios. These us usually bogus, but we still need them"""

    buffer = create_string_buffer(sizeof(HDGeometry))
    g = cast(buffer, POINTER(HDGeometry))
    result = libc.ioctl(fd, HDIO_GETGEO, byref(buffer))
    assert result == 0
    return g.contents

if __name__ == "__main__":
    fd = os.open("/dev/sdb", os.O_RDWR)
    print repr(get_disk_geometry(fd))

【讨论】:

使用import * 会污染你的命名空间,使程序更难阅读和调试。如果您需要简洁,请考虑使用import extralongmodulename as e ctypes 是我唯一使用过的模块,我同意,但 ctypes 是一个普遍的痛苦。我想将它导入为 C 或其他东西就可以了。

以上是关于为啥我不能在 python 中调用 HDIO_GETGEO?的主要内容,如果未能解决你的问题,请参考以下文章

为啥不能在 Python 中使用 dbus 调用 org.freedesktop.NetworkManager 中的方法?

为啥 2019 年我们仍然不能使用 ctypes 从 Python 调用 C++?

python中构建了一个类,在定义了一个函数时为啥括号第一个self有啥用,为啥不能给他赋值

为啥我不能在方法之外调用变量? [复制]

为啥我不能在 main 方法中调用私有变量?

Object在其子类中,为啥不能调用clone()???