Find out current working directory of a running process?
There are 3 methods that I'm aware of:
pwdx
$ pwdx <PID>
lsof
$ lsof -p <PID> | grep cwd
/proc
$ readlink -e /proc/<PID>/cwd
Examples
Say we have this process.
$ pgrep nautilus
12136
Then if we use pwdx
:
$ pwdx 12136
12136: /home/saml
Or you can use lsof
:
$ lsof -p 12136 | grep cwd
nautilus 12136 saml cwd DIR 253,2 32768 10354689 /home/saml
Or you can poke directly into the /proc
:
$ readlink -e /proc/12136/cwd/
/home/saml
I assume that you have the process ID in pid
. Most methods on most systems will require that the shell you're doing this from is running as the same user as the target process (or root).
On Linux and Solaris and perhaps some other System V unices:
cd /proc/$pid/cwd && pwd
On Linux (except embedded systems where readlink
is not available) but not Solaris:
readlink /proc/$pid/cwd
On just about any unix variant, you can use lsof
. Beware that if there is a newline, it will be printed as \n
(indistinguishable from backslash followed by n
). If you feel lucky, you can use the second form, which silently chokes on all whitespace in the directory name.
lsof -a -Fn -p $pid -d cwd | sed -e '1d' -e '2s/^n/'
lsof -p $pid | awk '$4=="cwd" {print $9}'
Bonus: if you need to cause a process to change its current directory, you can do it with a debugger. This is useful for example to move a long-running program that doesn't care about its current directory out of a directory that you want to remove. Not all programs appreciate having their current directory changed under their feet — for example a shell is likely to crash.
#!/bin/sh
# Use gdb to change the working directory of a process from outside.
# This could be generalized to a lot of other things.
if [ $# -ne 2 ]; then
echo 1>&2 "Usage: $0 PID DIR"
exit 120
fi
case "$1" in
*[!0-9]*) echo 1>&2 "Invalid pid \`$1'"; exit 3;;
esac
case "$2" in
*[\\\"]*)
echo 1>&2 "Unsupported character in directory name, sorry."
exit 3;;
esac
gdb -n -pid "$1" -batch -x /dev/stdin <<EOF
call chdir("$2")
detach
quit
EOF
If your system has /proc
, you can always do:
readlink -e /proc/$$/cwd
If you want to find out the CWD from a different process than the one you're interested in, you obviously need to replace $$
with the PID of your process of interest.