What's the best way to check if a volume is mounted in a Bash script?
What I'd really like is a method that I can use like this:
if <something is mounted at /mnt/foo>
then
<Do some stuff>
else
<Do some different stuff>
fi
Server Fault is a question and answer site for system and network administrators. It only takes a minute to sign up.
Sign up to join this communityAvoid using /etc/mtab
because it may be inconsistent.
Avoid piping mount
because it needn't be that complicated.
Simply:
if grep -qs '/mnt/foo ' /proc/mounts; then
echo "It's mounted."
else
echo "It's not mounted."
fi
(The space after the /mnt/foo
is to avoid matching e.g. /mnt/foo-bar
.)
if mountpoint -q /mnt/foo
then
echo "mounted"
else
echo "not mounted"
fi
or
mountpoint -q /mnt/foo && echo "mounted" || echo "not mounted"
mountpoint
originates in the "initscripts" package in Ubuntu/Debian.
mountpoint
is that it checks, in fact, if a mount point is mounted, but not if a device is mounted. If a device is passed with the -x
option it tells you the major/minor device number, but not if it's mounted.
Aug 14, 2017 at 9:46
util-linux
Jun 11, 2019 at 6:31
findmnt -rno SOURCE,TARGET "$1"
avoids all the problems in the other answers. It cleanly does the job with just one command.
Other approaches have these downsides:
grep -q
and grep -s
are an extra unnecessary step and aren't supported everywhere./proc/\*
isn't supported everywhere. (mountpoint
is also based on proc).mountinfo
is based on /proc/..cut -f3 -d' '
messes up spaces in path names.. listing mode is maintained for backward compatibility only.
For more robust and customizable output use findmnt(8), especially in your scripts.
Bash functions:
#These functions return exit codes: 0 = found, 1 = not found
isDevMounted () { findmnt --source "$1" >/dev/null;} #device only
isPathMounted() { findmnt --target "$1" >/dev/null;} #path only
isMounted () { findmnt "$1" >/dev/null;} #device or path
#Usage examples:
if isDevMounted "/dev/sda10";
then echo "device is mounted"
else echo "device is not mounted"
fi
if isPathMounted "/mnt/C";
then echo "path is mounted"
else echo "path is not mounted"
fi
#Universal (device OR path):
if isMounted "/dev/sda10";
then echo "device is mounted"
else echo "device is not mounted"
fi
if isMounted "/mnt/C";
then echo "path is mounted"
else echo "path is not mounted"
fi
findmnt(8)
command but I never really played with it. Frankly if I were to update some of my scripts that do this type of thing (or make new ones) on a Linux box (or where the command is available) this is what I'd do.
findmnt
has to be supplied with the parameter --source encfs
, otherwise it will always consider the directory to be mounted because it falls back to the parent mount.
grep
solution because if a mount path is weird, you can get false positives: e.g. if I mount /dev/mmcblk0p1
on ~/mnt/dev/sda1
, I could incorrectly thing that /dev/sda1
is mounted by the command mount | grep '/dev/sda1'
. I can't get a false positive using findmnt
. Good answer!
Oct 15, 2019 at 14:06
-rno
stuff needed here, if all the output is directed to dev/null
anyway?
A script like this isn't ever going to be portable. A dirty secret in unix is that only the kernel knows what filesystems are where, and short of things like /proc (not portable) it'll never give you a straight answer.
I typically use df to discover what the mount-point of a subdirectory is, and what filesystem it is in.
For instance (requires posix shell like ash / AT&T ksh / bash / etc)
case $(df $mount)
in
$(df /)) echo $mount is not mounted ;;
*) echo $mount has a non-root filesystem mounted on it ;;
esac
Kinda tells you useful information.
the following is what i use in one of my rsync backup cron-jobs. it checks to see if /backup is mounted, and tries to mount it if it isn't (it may fail because the drive is in a hot-swap bay and may not even be present in the system)
NOTE: the following only works on linux, because it greps /proc/mounts - a more portable version would run 'mount | grep /backup', as in Matthew's answer..
if ! grep -q /backup /proc/mounts ; then if ! mount /backup ; then echo "failed" exit 1 fi fi echo "suceeded." # do stuff here
grep -q ' /backup ' /proc/mounts
or mount | grep -q ' /backup '
. Or redirect to /dev/null if your grep doesn't support -q
(which is in the POSIX spec for grep these days).
Since in order to mount, you need to have a directory there anyway, that gets mounted over, my strategy was always to create a bogus file with a strange filename that would never be used, and just check for it's existence. If the file was there, then nothing was mounted on that spot...
I don't think this works for mounting network drives or things like that. I used it for flash drives.
How about comparing devices numbers? I was just trying to think of the most esoteric way..
#!/bin/bash
if [[ $(stat -c "%d" /mnt) -ne $(stat -c "%d" /mnt/foo) ]]; then
echo "Somethin mounted there I reckon"
fi
There a flaw in my logic with that ...
As a Function:
#!/usr/bin/bash
function somethingMounted {
mountpoint="$1"
if ! device1=$(stat -c "%d" $mountpoint); then
echo "Error on stat of mount point, maybe file doesn't exist?" 1>&2
return 1
fi
if ! device2=$(stat -c "%d" $mountpoint/..); then
echo "Error on stat one level up from mount point, maybe file doesn't exist?" 1>&2
return 1
fi
if [[ $device1 -ne $device2 ]]; then
#echo "Somethin mounted there I reckon"
return 0
else
#echo "Nothin mounted it seems"
return 1
fi
}
if somethingMounted /tmp; then
echo "Yup"
fi
The echo error messages are probably redundant, because stat will display the an error as well.
None of these satisfy the use case where a given directory is a sub directory within another mount point. For example, you might have /thing which is an NFS mount to host:/real_thing. Using grep for this purpose on /proc/mounts /etc/mtab or 'mount' will not work, because you will be looking for a mount point that doesn't exist. For example, /thing/thingy is not a mount point, but /thing is mounted on host:/real_thing. The best answer voted on here is actually NOT "the best way to determine if a directory/volumne is mounted". I'd vote in favour using 'df -P' (-P POSIX standards mode) as a cleaner strategy:
dev=`df -P /thing/thingy | awk 'BEGIN {e=1} $NF ~ /^\/.+/ { e=0 ; print $1 ; exit } END { exit e }'` && {
echo "Mounted via: $dev"
} || {
echo "Not mounted"
}
The output from running this will be:
Mounted via: host:/real_thing
If you want to know what the real mount point is, no problem:
mp=`df -P /thing/thingy | awk 'BEGIN {e=1} $NF ~ /^\/.+/ { e=0 ; print $NF ; exit } END { exit e }'` && {
echo "Mounted on: $mp"
} || {
echo "Not mounted"
}
The output from that command will be:
Mounted on: /thing
This is all very useful if you are trying to create some sort of chroot that mirrors mount points outside of the chroot, within the chroot, via some arbitrary directory or file list.
I like the answers that use /proc/mounts
, but I don't like doing a simple grep. That can give you false positives. What you really want to know is "do any of the rows have this exact string for field number 2". So, ask that question. (in this case I'm checking /opt
)
awk -v status=1 '$2 == "/opt" {status=0} END {exit status}' /proc/mounts
# and you can use it in and if like so:
if awk -v status=1 '$2 == "/opt" {status=0} END {exit status}' /proc/mounts; then
echo "yes"
else
echo "no"
fi
I think this is useful:
if awk '{print $2}' /proc/mounts | grep -qs "^/backup$"; then
echo "It's mounted."
else
echo "It's not mounted."
fi
This gets the second column of /proc/mounts
which is mount points.
Then it greps the output. Note the ^ and $, this prevents /backup from matching /mnt/backup or /backup-old etc.
This script will check if the drive is mounted and actually available. It can be written in more compact but I prefer to have it simple like this since I'm not that familiar with Bash. You may want to change the timeout, it is set to 10 sec. in the script.
MNT_DIR=/mnt/foo
df_result=$(timeout 10 df "$MNT_DIR")
[[ $df_result =~ $MNT_DIR ]]
if [ "$BASH_REMATCH" = "$MNT_DIR" ]
then
echo "It's available."
else
echo "It's not available."
fi
grep /etc/mtab for your mount point maybe?
This?:
volume="/media/storage"
if mount|grep $volume; then
echo "mounted"
else
echo "not mounted"
if
From: An Ubuntu forum
Although this is a Linux question, why not make it portable when it is easily done?
The manual page of grep
says:
Portable shell scripts should avoid both -q and -s and should redirect standard and error output to
/dev/null
instead.
So I propose the following solution:
if grep /mnt/foo /proc/mounts > /dev/null 2>&1; then
echo "Mounted"
else
echo "NOT mounted"
fi
-q
and -s
are specified by POSIX so there shouldn't be any portability issue with it anyway (now if not before - I've not kept track of what changes happen when).
Does it need to be any more complicated than this?
mount \
| cut -f 3 -d ' ' \
| grep -q /mnt/foo \
&& echo "mounted" || echo "not mounted"
grep -q /mnt/foo
will also match mount points /mnt/food
and /not/mnt/foo
... How about grep -qx /mnt/foo
?
-x
makes grep match only if the whole line matches.
cut -f 3 -d ' '
stumbles when mount path has a space in a filename.
Mar 15, 2018 at 14:07
Depends what you know about the volume you're checking for.
In the particular case I researched recently, where I was concerned to find if a particular flash drive was mounted, what works most easily is checking for the existence of /dev/disks/by-label/. If the device is plugged in, udev scripts make sure the link exists (and that it is removed when the device is unplugged).
(This is NOT a highly portable answer; it works on many modern Linux distributions, though, and the question was tagged for Linux, and it's a completely different approach from anything so far mentioned so it expands the possibilities.)
Create file under your mountpoint like check_mount
and then just test if it exists?
if [[ -f /something/check_mount ]]; then
echo "Mounted
RC=$?
else
Echo "Not mounted"
RC=0
fi
exit $RC
I had to do this in Chef for idempotence since when chef-client would run, the run would fail due to the volume already being mounted. At the time I write this, the Chef mount
resource has some kind of bug which wouldn't work with attributes the way I needed, so I mounted the volume using the execute
resource instead. Here's how I did it:
if not node['docker-server']['mountpoint'] == "none"
execute "set up mount" do
user "root"
command "mount -t ext4 #{node['docker-server']['mountpoint']} #{node['docker-server']['data-dir']}"
not_if "grep -qs #{node['docker-server']['data-dir']} /proc/mounts"
end
end
In case of any confusion, in my attributes file, I have the following:
default['docker-server']['mountpoint'] = "/dev/vdc"
default['docker-server']['data-dir'] = "/data"
The if not node['docker-server']['mountpoint'] == "none"
is a part of a case
statement where if the mount point on the server is not specified, the mount point defaults to none
.
/etc/mtab
,/proc/mounts
are linked to/proc/self/mounts
. (atleast on Fedora 20 it is)fdisk -l