Andrew
Andrew

Reputation: 241

perl - disk name on Linux

What module would you recommend to get a disk name on Linux? I've done some search on CPAN but all modules I've found are too old. In Bash I can use something like:

disk_name=$(df |grep -w '/'|awk '{print $1}'|cut -d/ -f3)
echo $disk_name
sda6

Please help me to understand how to do same in Perl. Thanks.

Upvotes: 1

Views: 1326

Answers (3)

Ilmari Karonen
Ilmari Karonen

Reputation: 50328

The "proper" way to list mounted disks on Linux is through the getmntent() system call, which can be accessed from Perl using the Quota module:

use Quota;

Quota::setmntent();
while (my ($dev, $path, $type, $opts) = Quota::getmntent()) {
    print "The root device is $dev.\n"  if $path eq "/";
}
Quota::endmntent();

As a bonus, using the Quota module to list device mount points should be fairly portable to other Unixish systems, which parsing various system files or the output of df may not be. Unfortunately, this seemingly basic module is not included in the standard Perl distribution, so you have to get it from CPAN (or from your distro's package repository — for example, Debian / Ubuntu have the libquota-perl package).


Ps. Simply splitting the device name on / and taking the third element (as your cut command does) is not a safe way to turn, say, /dev/sdb1 into sdb1. Some issues with it are that:

  1. Not all block devices have to live under /dev — it's really just a convention.
  2. Even if the device file is under /dev, it might be in a subdirectory of it. For example, my root filesystem is on the device /dev/disk/by-uuid/627f8512-f037-4c6c-9892-6130090c0e0f.
  3. Sometimes, the device name might not even be an actual filesystem path: for example, virtual or in-memory filesystems such as tmpfs are often mounted with the device name none, but it's possible to use any device name with them.

If you do want to get rid of the /dev/ part, I'd suggest a conservative approach using a regexp, for example like this:

if ($dev =~ m(^/dev/(.*)$)s) {
    print "The directory $path is mounted from device $1 under /dev.\n";
} else {
    print "The directory $path is not mounted from a device under /dev.\n"
}

Upvotes: 5

Aleks G
Aleks G

Reputation: 57306

What you're describing is not the disk name but the device name of the block device representing the partition mounted at root (/). On a regular computer it would normally be something like /dev/sdXN or /dev/hdXN with X being the disk number (primary hard drive is usually A, secondary is B, etc.) and N is the partition number on that device.

Provided you're always running on a unix system, you can try reading /etc/mtab file, which lists all mounted partitions, or the special file /proc/mounts, which pretty much does the same. You'll need to parse it afterwards to find the one you need and get the device name from it.

Alternatively, you can just run df as a process and get its input into perl, something like

open(DF, "df|");
@mount_points = <DF>;
close(DF);

and then iterate over the data to find what you need. I'm not aware of any modules of the top of my head that would do the job for you, but the code seems pretty simple to me anyway.

P.S. Note that Max OS X, while being a derivative of BSD, doesn't have the same file structure and therefore this approach wouldn't work. On Mac OS X, you can read file /etc/fstab.hd, which contains similar info but in a slightly different format.

Upvotes: 2

David Nehme
David Nehme

Reputation: 21572

One way to do just what you are doing in the question

df / | perl -ne 'm"^/\w+/(\w+)";print "$1\n" if defined $1;'

but using a CPAN library to do it is probably better.

Upvotes: 1

Related Questions