views:

424

answers:

6

The following, very non-robust shell code will give the mount point of $path:

 (for i in $(df|cut -c 63-99); do case $path in $i*) echo $i;; esac; done) | tail -n 1

Is there a better way to do this?

Postscript

This script is really awful, but has the redeeming quality that it Works On My Systems. Note that several mount points may be prefixes of $path.

Examples On a Linux system:

cas@txtproof:~$ path=/sys/block/hda1
cas@txtproof:~$ for i in $(df -a|cut -c 57-99); do case $path in $i*) echo $i;; esac; done| tail -1
/sys

On a Mac osx system

cas local$ path=/dev/fd/0
cas local$ for i in $(df -a|cut -c 63-99); do case $path in $i*) echo $i;; esac; done| tail -1
/dev

Note the need to vary cut's parameters, because of the way df's output differs: indeed, awk is better.

Answer It looks like munging tabular output is the only way within the shell, but

df /dev/fd/impossible  | tail -1 | awk '{ print $NF}'

is a big improvement on what I had. Note two differences in semantics: firstly, df $path insists that $path names an existing file, the script I had above doesn't care; secondly, there are no worries about dereferncing symlinks.

It's not difficult to write Python code to do the job.

+1  A: 

i don't know what your desired output is, therefore this is a guess

#!/bin/bash

path=/home
df | awk -v path="$path" 'NR>1 && $NF~path{
 print $NF
}'

Using cut with -c is not really reliable, since the output of df will be different , say a 5% can change to 10% and you will miss some characters. Since the mount point is always at the back, you can use fields and field delimiters. In the above, $NF is the last column which is the mount point.

ghostdog74
Yes, awk is better than cut, but I'd really like to get away from parsing the output of df. Note that mount points are hierarchically organised.
Charles Stewart
show what is $path, and show your desired output. give as much information in your question as possible.
ghostdog74
+4  A: 

df takes the path as parameter, so something like this should be fairly robust;

df "$path" | tail -1 | awk '{ print $6 }'
JesperE
As ndim said, this doesn't work for me because of wrapped lines in df output caused by LVM names. The quota command has a --no-wrap option but df doesn't seem to have one, too.
LonelyPixel
+2  A: 

In theory stat will tell you the device the file is on, and there should be some way of mapping the device to a mount point.

Douglas Leeder
I like this suggestion, but on mac os 10.4, running `stat -f"%Sdr"` returns `???r` for most filesystems.
Charles Stewart
I've posted a qn about the macosx behaviour to SU: http://superuser.com/questions/103755/whats-up-with-stat-on-macos-darwin-or-filesystems-without-names
Charles Stewart
+1  A: 

I would take the source code to df and find out what it does besides calling stat as Douglas Leeder suggests.

Line-by-line parsing of the df output will cause problems as those lines often look like

/dev/mapper/VOLGROUP00-logical--volume
                      1234567  1000000  200000  90% /path/to/mountpoint

With the added complexity of parsing those kinds of lines as well, probably calling stat and finding the mountpoint is less complex.

ndim
+1  A: 
mount | grep "^$path" | awk '{print $3}'
Dennis Williamson
A: 

I missed this when I looked over prior questions: Python: Get Mount Point on Windows or Linux, which says that os.path.ismount(path) tells if path is a mount point.

My preference is for a shell solution, but this looks pretty simple.

Charles Stewart