3

我有大约 10 个 EBS 卷附加到一个实例。下面是lsblk其中一些的例子。这里我们不能简单地将 xvdf 或 xvdp 挂载到某个位置,但实际点是要挂载的 xvdf1、xvdf2、xvdp。我想要一个脚本,允许我使用 python 遍历 xvdf、xvdp 等下的所有点。我是 python 的新手。

[root@ip-172-31-1-65 ec2-user]# lsblk
NAME    MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
xvdf    202:80   0   35G  0 disk 
├─xvdf1 202:81   0  350M  0 part 
└─xvdf2 202:82   0 34.7G  0 part
xvdp   202:0    0    8G  0 disk 
└─xvdp1 202:1    0    8G  0 part
4

3 回答 3

5

如果您有一个相对较新lsblk的 .json 文件,您可以轻松地将其 json 输出导入 python 字典,然后打开所有迭代的可能性。

# lsblk --version
lsblk from util-linux 2.28.2

例如,您可以运行以下命令来收集所有块设备及其子设备及其名称和挂载点。用于--help获取所有支持的列的列表。

# lsblk --json -o NAME,MOUNTPOINT
{
"blockdevices": [
    {"name": "vda", "mountpoint": null,
        "children": [
            {"name": "vda1", "mountpoint": null,
            "children": [
                {"name": "pv-root", "mountpoint": "/"},
                {"name": "pv-var", "mountpoint": "/var"},
                {"name": "pv-swap", "mountpoint": "[SWAP]"},
            ]
            },
        ]
    }
]
}

因此,您只需将该输出通过管道传输到文件中并使用 python 的 json 解析器。或者直接在脚本中运行命令,如下例所示:

#!/usr/bin/python3.7

import json
import subprocess

process = subprocess.run("/usr/bin/lsblk --json -o NAME,MOUNTPOINT".split(), 
                            capture_output=True, text=True)

# blockdevices is a dictionary with all the info from lsblk.
# Manipulate it as you wish.
blockdevices = json.loads(process.stdout)


print(json.dumps(blockdevices, indent=4))
于 2020-02-06T14:59:01.150 回答
1
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
def parse(file_name):
        result = []
        with open(file_name) as input_file:
                for line in input_file:
                        temp_arr = line.split(' ')
                        for item in temp_arr:
                                if '└─' in item or '├─'  in item:
                                        result.append(item.replace('└─','').replace('├─',''))
        return result


def main(argv):
        if len(argv)>1:
                print 'Usage: ./parse.py input_file'
                return
        result = parse(argv[0])
        print result
if __name__ == "__main__":
   main(sys.argv[1:])

以上就是你需要的。您可以修改它以更好地解析 lsblk 的输出。
用法:
1. 将 lsblk 的输出保存到文件中。例如运行这个命令:lsblk > output.txt
2。python parse.py output.txt

于 2015-08-03T12:03:16.990 回答
0

我出于自己的目的重新混合了 minhhn2910 的答案,以使用加密分区、标签并在树状 dict 对象中构建输出。当我在 GitHub 上遇到极端情况时,我可能会保留更新的版本,但这里是基本代码:

#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
import re
import pprint

def parse_blk(blk_filename):
    result = []
    with open(blk_filename) as blk_file:
        disks = []
        for line in blk_file:
            if line.startswith('NAME'): # skip first line
                continue
            blk_list = re.split('\s+', line)
            node_type = blk_list[5]
            node_size = blk_list[3]
            if node_type in set(['disk', 'loop']):
                # new disk
                disk = {'name': blk_list[0], 'type': node_type, 'size': node_size}
                if node_type == 'disk':
                    disk['partitions'] = []
                disks.append(disk)
                # get size info if relevant
                continue
            if node_type in set(['part', 'dm']):
                # new partition (or whatever dm is)
                node_name = blk_list[0].split('\x80')[1]
                partition = {'name': node_name, 'type': node_type, 'size': node_size}
                disk['partitions'].append(partition)
                continue
            if len(blk_list) > 8: # if node_type == 'crypt':
                # crypt belonging to a partition
                node_name = blk_list[1].split('\x80')[1]
                partition['crypt'] = node_name


        return disks

def main(argv):
    if len(argv)>1:
        print 'Usage: ./parse.py blk_filename'
        return
    result = parse_blk(argv[0])
    pprint.PrettyPrinter(indent=4).pprint(result)

if __name__ == "__main__":
    main(sys.argv[1:])

它也适用于您的输出:

$ python check_partitions.py blkout2.txt
[   {   'name': 'xvdf',
        'partitions': [   {   'name': 'xvdf1', 'size': '350M', 'type': 'part'},
                          {   'name': 'xvdf2', 'size': '34.7G', 'type': 'part'}],
        'size': '35G',
        'type': 'disk'},
    {   'name': 'xvdp',
        'partitions': [{   'name': 'xvdp1', 'size': '8G', 'type': 'part'}],
        'size': '8G',
        'type': 'disk'}]

这就是它在使用 docker 环回设备和加密分区的稍微复杂的场景中的工作方式。

$ python check_partitions.py blkout.txt
[   {   'name': 'sda',
        'partitions': [   {   'crypt': 'cloudfleet-swap',
                              'name': 'sda1',
                              'size': '2G',
                              'type': 'part'},
                          {   'crypt': 'cloudfleet-storage',
                              'name': 'sda2',
                              'size': '27.7G',
                              'type': 'part'}],
        'size': '29.7G',
        'type': 'disk'},
    {   'name': 'loop0', 'size': '100G', 'type': 'loop'},
    {   'name': 'loop1', 'size': '2G', 'type': 'loop'},
    {   'name': 'mmcblk0',
        'partitions': [{   'name': 'mmcblk0p1',
                              'size': '7.4G',
                              'type': 'part'}],
        'size': '7.4G',
        'type': 'disk'}]
于 2015-10-01T15:32:17.603 回答