首页 > 解决方案 > 在脚本中包装 linux 和 windows 的 python 代码 - 最好的方法?

问题描述

我喜欢为工作中的同事编写有用的 cli 脚本,但我们在不同的操作系统上总是遇到同样的问题。我发现了以下问题,但与那些具有更高框架(如BeeWare)的解决方案相比,我正在寻找在 cli 上运行并且对所有类型的 python 程序员都非常可读的非常低级的脚本。所以我决定创建一个用例和一个示例 ipchecker.py 脚本来说明我与朋友分享我的食谱的首选概念。每个人都可以从中受益的最有用的情况是查看自己的 IP 地址。结帐更多关于 IPS Python

我知道有很多方法可以检查 IPS,但我想以一种可以被视为通用结构的方式来检查 IPS,以便将来添加更多复杂的东西。所以让我们从这个脚本开始:

user@pc : pyton ipchecker.py # 打印我的地址列表

用户@pc:['192.168.178.11', '172.18.1.9', '172.00.0.1', '2ak1:c22:c898:2d00:9788:6b0c:9ws2:4ss4', '2a00:c32:c318:23d0: 1a2c:23f5:4rs0:88r1']

这是一个好方法吗?

ipchecker.py

    import subprocess


    class LinuxIpChecker:
        """
        Only for linux
        """

        def __init__(self) -> None:
            self.runOnLinux()

        def runOnLinux(self):
            output = subprocess.check_output(['hostname', '-I'])
            addresses = [
                i for i in str(
                    output.decode(
                        'utf-8'
                    ).replace('\n', '')
                ).split(' ') if len(i) > 0
            ]

            print(addresses)
            return addresses


    class IpChecker(object):
        """
        Just run and do not bother if windows or linux
        """

        def __init__(self) -> None:

            self.run()

        def run(self):
            try:
                self.runOnLinux()
                return
            except Exception as e:
                print(e)

            try:
                self.runOnWindows()
            except Exception as e:
                print('runOnWindows ::: \n', e)

        def runOnLinux(self):

            output = subprocess.check_output(['hostname', '-I'])
            addresses = [i for i in str(output.decode(
                'utf-8'
            ).replace('\n', '')).split(' ') if len(i) > 0
            ]

            print(addresses)
            return addresses

        def runOnWindows(self):
            addresses = []
            for i in self.getIPAddresses():
                print(i)
                addresses.append(i)

            return addresses

        def getIPAddresses():
            """
            credits to https://stackoverflow.com/users/18745/dzinx
            """
            from ctypes import Structure, windll, sizeof
            from ctypes import c_ulong, c_uint, c_ubyte, c_char
            from ctypes import POINTER, byref

            MAX_ADAPTER_DESCRIPTION_LENGTH = 128
            MAX_ADAPTER_NAME_LENGTH = 256
            MAX_ADAPTER_ADDRESS_LENGTH = 8

            class IP_ADDR_STRING(Structure):
                pass
            LP_IP_ADDR_STRING = POINTER(IP_ADDR_STRING)
            IP_ADDR_STRING._fields_ = [
                ("next", LP_IP_ADDR_STRING),
                ("ipAddress", c_char * 16),
                ("ipMask", c_char * 16),
                ("context", c_ulong)]

            class IP_ADAPTER_INFO (Structure):
                pass
            LP_IP_ADAPTER_INFO = POINTER(IP_ADAPTER_INFO)
            IP_ADAPTER_INFO._fields_ = [
                ("next", LP_IP_ADAPTER_INFO),
                ("comboIndex", c_ulong),
                ("adapterName", c_char * (MAX_ADAPTER_NAME_LENGTH + 4)),
                ("description", c_char * (MAX_ADAPTER_DESCRIPTION_LENGTH + 4)),
                ("addressLength", c_uint),
                ("address", c_ubyte * MAX_ADAPTER_ADDRESS_LENGTH),
                ("index", c_ulong),
                ("type", c_uint),
                ("dhcpEnabled", c_uint),
                ("currentIpAddress", LP_IP_ADDR_STRING),
                ("ipAddressList", IP_ADDR_STRING),
                ("gatewayList", IP_ADDR_STRING),
                ("dhcpServer", IP_ADDR_STRING),
                ("haveWins", c_uint),
                ("primaryWinsServer", IP_ADDR_STRING),
                ("secondaryWinsServer", IP_ADDR_STRING),
                ("leaseObtained", c_ulong),
                ("leaseExpires", c_ulong)]
            GetAdaptersInfo = windll.iphlpapi.GetAdaptersInfo
            GetAdaptersInfo.restype = c_ulong
            GetAdaptersInfo.argtypes = [LP_IP_ADAPTER_INFO, POINTER(c_ulong)]
            adapterList = (IP_ADAPTER_INFO * 10)()
            buflen = c_ulong(sizeof(adapterList))
            rc = GetAdaptersInfo(byref(adapterList[0]), byref(buflen))
            if rc == 0:
                for a in adapterList:
                    adNode = a.ipAddressList
                    while True:
                        ipAddr = adNode.ipAddress
                        if ipAddr:
                            yield ipAddr
                        adNode = adNode.next
                        if not adNode:
                            break


    if __name__ == '__main__':
        result = LinuxIpChecker()

标签: pythonlinuxwindowsscriptingarchitecture

解决方案


推荐阅读