Skip to main content
Code Review

Return to Answer

added 10 characters in body
Source Link
200_success
  • 145.6k
  • 22
  • 190
  • 479
from glob import glob
from os.path import basename, dirname
def physical_drives():
 drive_glob = '/sys/block/*/device'
 return [basename(dirname(pd)) for pd in glob(drive_glob)]
def partitions(disk):
 if disk.startswith('.') or '/' in disk:
 raise ValueError('Invalid disk name {0}'.format(disk))
 part_globpartition_glob = '/sys/block/{0}/*/start'.format(disk)
 return [basename(dirname(p)) for p in glob(part_globpartition_glob)]
from glob import glob
from os.path import basename, dirname
def physical_drives():
 drive_glob = '/sys/block/*/device'
 return [basename(dirname(p)) for p in glob(drive_glob)]
def partitions(disk):
 if disk.startswith('.') or '/' in disk:
 raise ValueError('Invalid disk name {0}'.format(disk))
 part_glob = '/sys/block/{0}/*/start'.format(disk)
 return [basename(dirname(p)) for p in glob(part_glob)]
from glob import glob
from os.path import basename, dirname
def physical_drives():
 drive_glob = '/sys/block/*/device'
 return [basename(dirname(d)) for d in glob(drive_glob)]
def partitions(disk):
 if disk.startswith('.') or '/' in disk:
 raise ValueError('Invalid disk name {0}'.format(disk))
 partition_glob = '/sys/block/{0}/*/start'.format(disk)
 return [basename(dirname(p)) for p in glob(partition_glob)]
Source Link
200_success
  • 145.6k
  • 22
  • 190
  • 479

lsblk

The -s option to lsblk was introduced to util-linux rather recently, in release 2.22. You may experience compatibility issues on slightly older GNU/Linux installations.

But I don't see why you would want the -s option at all — it just gives you an inverted device tree. For example, on my machine:

$ lsblk -o name -n -s -l
sda1
sda
sda2
sda
sr0
vg-root
sda3
sda
vg-var
sda3
sda
vg-data
sda3
sda

In the output, sda appears multiple times. To understand the output, you need to drop the -l flag so that the list appears in tree form:

$ lsblk -o name -n -s
sda1
└─sda
sda2
└─sda
sr0
vg-root
└─sda3
 └─sda
vg-var
└─sda3
 └─sda
vg-data
└─sda3
 └─sda

Now, it's more apparent that the -s option isn't helpful. If you drop it, then the output makes more sense:

$ lsblk -o name -n
sda
├─sda1
├─sda2
└─sda3
 ├─vg-root
 ├─vg-var
 └─vg-data
sr0
$ lsblk -o name -n -l
sda
sda1
sda2
sda3
vg-root
vg-var
vg-data
sr0

To list the devices on sda, it would be better to run lsblk -o name -n -l /dev/sda — that would immediately drop sr0 from consideration, for example. Note that LVM volumes (such as vg-root above) would still appear in the output. I don't think that doing a substring search (if x != disk and disk in x in your code) is a reliable filter. It could be fooled if there are more than 26 physical disks: the 27th disk would be named sdaa. It might also be fooled by exceptionally tricky naming of LVM volumes.

Subprocess execution

Whenever practical, I recommend avoiding the shell when executing subprocesses. The shell introduces a set of potential security vulnerabilities — for example, shenanigans with the PATH environment variable. Best practice would be to run the command with a specific executable and pre-parsed command-line options:

run('/bin/lsblk -o name -n -s -l'.split(), stdout=PIPE)

Alternative solution

I actually wouldn't bother with parsing the output of lsblk at all. After all, lsblk is just a way to report the contents of the sysfs filesystem. You would be better off inspecting /sys directly.

from glob import glob
from os.path import basename, dirname
def physical_drives():
 drive_glob = '/sys/block/*/device'
 return [basename(dirname(p)) for p in glob(drive_glob)]
def partitions(disk):
 if disk.startswith('.') or '/' in disk:
 raise ValueError('Invalid disk name {0}'.format(disk))
 part_glob = '/sys/block/{0}/*/start'.format(disk)
 return [basename(dirname(p)) for p in glob(part_glob)]
lang-py

AltStyle によって変換されたページ (->オリジナル) /