如何使用 python 从 xcrun xctrace list devices 获取设备?

How can I get devices from xcrun xctrace list devices using python?

我想获得从 xcrun xctrace list devices 命令返回的某种设备列表,但由于子进程未返回字符串而遇到问题。

命令的命令行输出示例为:

>xcrun xctrace list devices
== Devices ==
MacBook Pro (8DC7892B-AC67-5E83-A78A-DD9208A1B181)
iPhone 12 Pro (14.4) (4D60C438-4FD5-4E9A-94CF-C5KSHAJBDKNC22F)

== Simulators ==
Apple TV (14.3) (EF539FA3-D5E4-438C-B13E-0F815C0EBD25)
Apple TV 4K (14.3) (764160B1-AA54-4B22-843E-F59C4FEE2811)
Apple TV 4K (at 1080p) (14.3) (C89291C1-E185-43A5-9864-AA3FFC2CCAB9)
iPad (8th generation) (14.4) (FFD58713-613C-4A22-8A22-91BBECEE365B)
iPad Air (4th generation) (14.4) (467C9FAC-AB3B-4AB0-8835-B4FDCAAD2E9D)
iPad Pro (11-inch) (2nd generation) (14.4) (72EA7440-36D8-489A-BE0E-2D92A5A4F17C)
iPad Pro (12.9-inch) (4th generation) (14.4) (B17432A5-B485-4205-A0C8-0B7C9A2631E9)
iPad Pro (9.7-inch) (14.4) (BAA58BC1-E82A-4280-9F4F-F200B62B8E9C)
iPhone 11 (14.4) (F7DEADEF-810D-49EB-A51E-1705953F5AAF)
iPhone 11 Pro (14.4) (64276DB1-506E-4E36-9424-23B86A7A7475)
iPhone 11 Pro Max (14.4) (1DB48B92-F8CC-4656-AD55-1C4F15DD1D78)
iPhone 12 (14.4) (F03441B9-BADA-4520-B2DE-E17A0DEC5181)
iPhone 12 (14.4) + Apple Watch Series 5 - 44mm (7.2) (C03D3DF3-1F3A-4F21-A384-32ABF02D8AE6)
iPhone 12 Pro (14.4) (4D60C438-4FD5-4E9A-94CF-C5D4BA04C22F)
iPhone 12 Pro (14.4) + Apple Watch Series 6 - 40mm (7.2) (C0D0B9A2-C3A9-42E2-B2A7-3278969BFBD5)
iPhone 12 Pro Max (14.4) (B0BEB55F-F273-4266-A866-FD6FA22BBE30)
iPhone 12 Pro Max (14.4) + Apple Watch Series 6 - 44mm (7.2) (3F63E87A-08BF-4CCF-B748-001576DE3936)
iPhone 12 mini (14.4) (286AD04E-2861-402B-909B-02EFF09F4AD8)
iPhone 12 mini (14.4) + Apple Watch Series 5 - 40mm (7.2) (7B19B87E-F77B-4301-9D49-967AD5091B8A)
iPhone 8 (14.4) (0641E046-ABD6-4C98-9015-1ACA7306ECA6)
iPhone 8 Plus (14.4) (0DA40E24-BBCD-4C5B-9E8D-5047014474C5)
iPhone SE (2nd generation) (14.4) (28284B6D-D626-4A52-89A8-D5E536235EA8)
iPod touch (7th generation) (14.4) (9DF9A23C-2BDE-45F5-BCAB-F671981FACA8)

如您所见,所需的数据行将来自包含 == Devices == 的行和包含 == Simulators ==.

的行之间

我尝试使用 subprocess 来获取 xcrun xctrace list devices 命令的输出,但是它并没有像我期望的那样出现。您可以在下面看到在 IPython 中命令运行并产生输出,但是分配给它的变量是空的:

    In [2]: import subprocess

In [3]: x = subprocess.check_output(['xcrun', 'xctrace', 'list', 'devices'])
== Devices ==
MacBook Pro (8DC7892B-AC67-5E83-A78A-DD9208A1B181)
iPhone 12 Pro (14.4) (4D60C438-4FD5-4E9A-94CF-C5KSHAJBDKNC22F)
== Simulators ==
Apple TV (14.3) (EF539FA3-D5E4-438C-B13E-0F815C0EBD25)
Apple TV 4K (14.3) (764160B1-AA54-4B22-843E-F59C4FEE2811)
Apple TV 4K (at 1080p) (14.3) (C89291C1-E185-43A5-9864-AA3FFC2CCAB9)
iPad (8th generation) (14.4) (FFD58713-613C-4A22-8A22-91BBECEE365B)
iPad Air (4th generation) (14.4) (467C9FAC-AB3B-4AB0-8835-B4FDCAAD2E9D)
iPad Pro (11-inch) (2nd generation) (14.4) (72EA7440-36D8-489A-BE0E-2D92A5A4F17C)
iPad Pro (12.9-inch) (4th generation) (14.4) (B17432A5-B485-4205-A0C8-0B7C9A2631E9)
iPad Pro (9.7-inch) (14.4) (BAA58BC1-E82A-4280-9F4F-F200B62B8E9C)
iPhone 11 (14.4) (F7DEADEF-810D-49EB-A51E-1705953F5AAF)
iPhone 11 Pro (14.4) (64276DB1-506E-4E36-9424-23B86A7A7475)
iPhone 11 Pro Max (14.4) (1DB48B92-F8CC-4656-AD55-1C4F15DD1D78)
iPhone 12 (14.4) (F03441B9-BADA-4520-B2DE-E17A0DEC5181)
iPhone 12 (14.4) + Apple Watch Series 5 - 44mm (7.2) (C03D3DF3-1F3A-4F21-A384-32ABF02D8AE6)
iPhone 12 Pro (14.4) (4D60C438-4FD5-4E9A-94CF-C5D4BA04C22F)
iPhone 12 Pro (14.4) + Apple Watch Series 6 - 40mm (7.2) (C0D0B9A2-C3A9-42E2-B2A7-3278969BFBD5)
iPhone 12 Pro Max (14.4) (B0BEB55F-F273-4266-A866-FD6FA22BBE30)
iPhone 12 Pro Max (14.4) + Apple Watch Series 6 - 44mm (7.2) (3F63E87A-08BF-4CCF-B748-001576DE3936)
iPhone 12 mini (14.4) (286AD04E-2861-402B-909B-02EFF09F4AD8)
iPhone 12 mini (14.4) + Apple Watch Series 5 - 40mm (7.2) (7B19B87E-F77B-4301-9D49-967AD5091B8A)
iPhone 8 (14.4) (0641E046-ABD6-4C98-9015-1ACA7306ECA6)
iPhone 8 Plus (14.4) (0DA40E24-BBCD-4C5B-9E8D-5047014474C5)
iPhone SE (2nd generation) (14.4) (28284B6D-D626-4A52-89A8-D5E536235EA8)
iPod touch (7th generation) (14.4) (9DF9A23C-2BDE-45F5-BCAB-F671981FACA8)

In [4]: x
Out[4]: b''

这目前对我有用。请注意 xcrun 输出到 stderr 并且必须重定向到 stdoutsubprocess.check_output() 的输出是字节文字而不是字符串,需要对其进行解码(因此 Out[4] 中的 b'')。参见:What does the 'b' character do in front of a string literal?

下面使用xcrun获取设备和模拟器的详细信息,然后使用正则表达式提取物理设备的详细信息,并使用模拟器部分的开始作为停止点。

IOS_REGEX_PATTERN = re.compile(r"^(.+) \((.+)\) \((.+)\)$")
...
def ios_devices_get():
    command = "xcrun xctrace list devices 2>&1"
    devices_string = subprocess.check_output(command, shell=True).decode("utf-8")
    devices_list = re.split(r"\n+", devices_string)

    device_entries = []
    regex_exit_pattern = re.compile(r"Simulators")
    for device_details in devices_list:
        if regex_exit_pattern.search(device_details):
            break
        device_match = IOS_REGEX_PATTERN.match(device_details)
        if device_match:
            device_entries.append(device_match.string)
    return device_entries