Hello,

I have a script written the unix shell language (NOT in bash or any other shell, in sh) that prints the mount point of a given usb (i.e, it takes the path of a usb (such as /dev/sdb1) as an argument). Here it is:

#!/bin/sh
# usage: get_mount [path]
# returns: mount pount of given usb path

pth=$1
echo $pth
mountPoint="`df -h | grep $pth | tr -s \" \"| cut \"-d \" -f6`"
echo $mountPoint

The problem is, when I run this, it just prints a blank string, and I know the command works because I've tried it in a terminal with no problem: it's just assigning it to a variable is what's not working. Anyone have any ideas? Thx in advance!

Edited 5 Years Ago by dark3lf: n/a


It works for me.

But you could simplify the code (there's no need for external commands):

LF='
'
mountPoint=`df -h "$pth"`
mountPoint=${mountPoint#*"$LF"}

Or, if you want to use a Bourne shell rather than a standard Unix shell:

mountPoint=`df -h "$pth" | { read; read -r x; set -f; echo $x; }`

Edited 5 Years Ago by cfajohnson: n/a

Try

mountPoint="`df -h | grep $pth | tr -s ' ' | cut -d ' ' -f6`"

BTW, you could significantly simplify things by piping df output to awk

Correction to my previous post, to extract just the mount point:

mountPoint=`df "$pth"`
mountPoint=${mountPoint##* }

Bourne shell version:

mountPoint=`df "$pth" | {
 read       ## header
 read -r a b c d e f
 echo "$f"
 }`

Edited 5 Years Ago by cfajohnson: n/a

Simpler would be:

#!/bin/sh
# usage: get_mount path
# returns: mount pount of given usb path

if [ $# -eq 1 ]; then
    df -h | awk /$1/'{print $6}'
else
    echo "Usage: `basename $0` path"
fi

# One liner:
# [ $# -eq 1 ] && df -h | awk /$1/'{print $6}' ||  echo "Usage: `basename $0` path"

Couple of comments:
1. awk works in most cases and code looks cleaner. Output of df is tabular and awk is best suited for it.
2. You wrote [path] in usage comment. "[]" in unix syntax's syntax means "optional". Nothing or "{}" mean mandatory.

Simpler would be:

#!/bin/sh
# usage: get_mount path
# returns: mount pount of given usb path

if [ $# -eq 1 ]; then
    df -h | awk /$1/'{print $6}'


What if $1 is "Used" or "Available"?

It will also fail if there is whitespace in $1.

$1 should be used as an argument to df, not a pattern in awk.
And I'd recommend using 'df -P', or it might split the output onto two lines (I forgot that, too):

df -Ph "$1" | ...
else
    echo "Usage: `basename $0` path"


There's no need for an external command, and error messages should be sent to stderr:

echo "Usage: ${0##*/} path" >&2
fi

# One liner:
# [ $# -eq 1 ] && df -h | awk /$1/'{print $6}' ||  echo "Usage: `basename $0` path"

Couple of comments:
1. awk works in most cases and code looks cleaner. Output of df is tabular and awk is best suited for it.


Whereas my code will work in all cases (once -P is added).

I don't use awk when there will only be a few lines to be read. The shell is much faster.

What if $1 is "Used" or "Available"?

I didn't get what you mean by Used or Available?

It will also fail if there is whitespace in $1.
$1 should be used as an argument to df, not a pattern in awk.

Yes. Soln is quite clear as well I guess. "/$1/"
Also although what you say is correct (pass it to df not awk) the difference is if you wanna pass it to df you need to know exact string, to awk it'll be a regex.
E.g. if passed to df: xxx.sh sda3 won't work, but when passed to awk xxx.sh sda3 will still give you the mount point for say /dev/sda3.

And I'd recommend using 'df -P', or it might split the output onto two lines (I forgot that, too):
There's no need for an external command, and error messages should be sent to stderr: echo "Usage: ${0##*/} path" >&2

Good point.

I don't use awk when there will only be a few lines to be read. The shell is much faster.

As a general coding practice yes. But in this case speed won't matter.
Prime reason why awk is my first choice is because those who donno awk can still guess what's {print $1} but those who donno shell won't understand most of the code you posted.

This article has been dead for over six months. Start a new discussion instead.