Detecting mount containing running script
Hey forum,
Is there a recommended approach for a Bash script to find at runtime the device which contains the mount which contains the running script? I have a script which runs off of a removable optical media and I'd like it to eject the media when it is done, but the 'eject' command needs a device path.
~ Kip
Re: Detecting mount containing running script
Something like
Code:
mntpoint=`df "$0"|awk 'NR==2{print $NF}'`
exec eject "$mntpoint"
Re: Detecting mount containing running script
Quote:
Originally Posted by
schragge
Something like
Code:
mntpoint=`df "$0"|awk 'NR==2{print $NF}'`
exec eject "$mntpoint"
Clever (and necessary) use of 'exec'....
Re: Detecting mount containing running script
Thanks folks. This is what I've come up with based on some of the feedback and researching a bit more BASH.
Code:
# Eject the media only if we are running off of removable media...
EjectRemovableMedia()
{
# Get full directory name containing this script no matter where it is
# called from...
AUTORUN_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
# Find the mount point it is located on...
MOUNT_POINT=`df "$AUTORUN_DIR" | awk 'NR==2{print $NF}'`
# Alert user of our intentions...
echo -n "Checking if" $MOUNT_POINT "is removable media..."
# Eject if it is removable media. That is, under /media/* according to sect
# 3.11.1 of the FHS...
if [[ $MOUNT_POINT == /media/* ]]; then
# Eject the media...
echo -e $SYMBOL_STATUS_OK
echo -n "Ejecting..."
eject $MOUNT_POINT 2> /dev/null
# Old approach: eject the disc by first trying CDROM eject method, then
# by SCSI method...
# eject -r -s 2> /dev/null
# Report whether it was successful or not...
if [ $? == 0 ]; then
echo -e $SYMBOL_STATUS_OK
else
echo -e $SYMBOL_STATUS_FAIL
fi
# Not running off of removable media, so don't try to eject...
else
echo -e $SYMBOL_STATUS_FAIL
fi
}
I could prefix eject with exec, but I wasn't sure I understood fully why it was necessary and when I should be using it.
~ Kip
Re: Detecting mount containing running script
Re: Detecting mount containing running script
Quote:
Originally Posted by
slavik
man exec
Thanks Slavik, but that's a given. It should have gone without saying that I wasn't satisfied with the man page.
Re: Detecting mount containing running script
Because the file with your script is open, so you can't unmount the filesystem that holds it. 'exec' replaces the script by another process, so the file is closed and the media can be unmounted.
Re: Detecting mount containing running script
+1 to what slavic and ofnuts said. Slavik's adivice was well-minded, but it might be misleading if you don't have package manpages-posix installed. The manual page he meant is exec(1posix). Since exec is impemented as bash builtin, you may also want to look it up in the bash info manual, or in the ABS.
Concerning your code, I'd probably rewrite this
Code:
AUTORUN_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
as
Code:
AUTORUN_DIR=$(readlink -f "$0")
Strictly speaking, even this is not needed as df is able to walk through symlinks, so should be enough.
BTW, better not name your script variables in all-caps as it may interfere with environment variables.
Also, if the only purpose of finding the mount point is to check whether it's a removable media then better approach would be directly evaluating device name:
Code:
device=$(df "$0"|awk 'NR>1{print $1}')
removable=$(lsblk -r -n -o RM $device)
if ((removable))
then echo Running off of removable media
else echo Running off of fixed drive
fi
Just for fun, doing the above snippet in one pass:
Code:
((`lsblk -rnorm $(df "$0"|sed '1d;s/ .*//')`))&&media_type=removable||media_type=fixed
echo Running off of $media_type media
Re: Detecting mount containing running script
Quote:
Originally Posted by
schragge
Something like
Code:
mntpoint=`df "$0"|awk 'NR==2{print $NF}'`
exec eject "$mntpoint"
I thought it was best to avoid use of exec. Would this work with ` qoutes?
Code:
mntpoint=`df "$0"|awk 'NR==2{print $NF}'`
`eject "$mntpoint"`
Re: Detecting mount containing running script
No, it wouldn't. To begin with, if eject returned some output, the shell would interpret it as a command. Fortunately, eject normally outputs nothing, so in this particular case, bare command substitution would be equivalent to executing eject in a subshell:
Code:
(eject "$mntpoint")
The script would end up waiting for the eject command to end with consequences described by ofnuts above. BTW what's wrong with using exec?