June 04, 2007, 4:21 PM — Send in your Unix questions today! |
See additional Unix tips and tricks
We have looked at the fuser command before to display information about
what users or processes are keeping file systems busy. This command
can save you a lot of time tracking when you need to quickly determine
how a file system or a particular file is being used, particularly when
you cannot unmount a file system due to current usage.
Today, we will look at a script that provides more information on the
processes keeping a file system busy by using fuser to supply process IDs
to ps and ps to then display additional information about each process.
The first thing this particular script does is request that the user
select the file system that he is concerned about. We do this with a
select statement. However, to ensure that we are looking only at locally
mounted file systems, we will pipe our df output through a "grep '^/dev"
command (i.e., we will tell the script to only list entries that start
with "/dev").
Once the user has selected the file system he is interested in, the $FS
parameter contains its name. If he mistakenly types the file system name
instead of the numeric designator from the menu or enters a number that
doesn't correspond to an item in the list, he will get an error and exit
the script.
#!/bin/bash
#
# fbusy: identify processes using file system, uses fuser
echo "select a file system by number:"
select FS in `df -k | grep "^/dev" | awk '{print $NF}'`
do
if [ "$FS" == "" ]; then
echo "invalid selection"
exit 1
fi
break
done
At this point in the script, the user will have selected a file system.
The next thing we do is print a banner including the file system name.
echo Processes using $FS echo ========================================
We then use the fuser command to find PIDs of processes which are using
the particular file system. Note that we are sending standard error to
/dev/null -- twice. In the parenthesized portion of the syntax, the
use of /dev/null essentially strips the letters (such as "c", "m", "o"
and such that tell how each process is using the file system) from
fuser's output, thus providing the ps command with a clean list of PIDs.
The second use of /dev/null keeps our users from having to look at an
ugly set of errors if the fuser command finds no processes are running
and then presents an empty process list of ps.
The ps command uses a -o option to select a series of process variables
we want to see and retrieves this information for all the processes located
by fuser.
ps -o uid,pid,ppid,tty,time,args -p "$(fuser -c $FS 2>/dev/null)" 2>/dev/null
Running this script, you would see something like this:
boson> ./fbusy select a file system: 1) / 3) /usr/local 5) /mail 2) /export/home 4) /var/spool/mqueue 6) /opt #? 2 Processes using /export/home ======================================== UID PID PPID TT TIME COMMAND 1111 28414 26208 pts/2 0:00 /bin/bash ./fbusy 1111 26208 26206 pts/2 0:00 -bash 5026 22948 22947 pts/3 0:00 telnet 66.77.88.99 5026 22947 22945 pts/3 0:00 -bash
In this example, we can see that four processes are keeping /export/home
busy. We also see the UID, parent process and terminal, process time
and the particular command that is being run.
We lose some information by sending fuser's standard error to /dev/null.
The letters ("c" and such) that were sent to the bit bucket could help
the user understand how each of the particular process is busying the
particular file system. For example, "c" indicates the process is using
the file system as its current directory while "m" indicates that the
process is using a file mapped with mmap.














