254

What command(s) can one use to find out the current working directory (CWD) of a running process? These would be commands you could use externally from the process.

0

6 Answers 6

331

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
7
  • 3
    I would say /proc is canonical, with lsof being useful, but pwdx is cool. Oct 10, 2013 at 0:33
  • 6
    Not all Unices have /proc. Oct 10, 2013 at 9:30
  • A similar but different question: unix.stackexchange.com/questions/173868/… Dec 12, 2014 at 5:03
  • 1
    pwdx works for me.
    – aroth
    Feb 8, 2016 at 7:11
  • 1
    In Ubuntu Server 18.04 the above commands require root privileges. At least in OpenBSD, you can see this answer to my U&L question.
    – Paul
    Jul 27, 2021 at 15:12
30

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
7
  • Nice touch adding the details in about moving. Good little nugget to add to the site!
    – slm
    Oct 10, 2013 at 0:56
  • Can you comment at all on the ubiquity of pwdx on other Unixes?
    – slm
    Oct 10, 2013 at 1:00
  • On OpenBSD, at least, lsof only reports the mount point of the process's CWD.
    – kurtm
    Oct 10, 2013 at 1:11
  • @slm pwdx is present on Solaris since the 20th century, Linux since the mid-2000s (imitating Solaris, says the man page). Not present on any other unix AFAIK. Oct 10, 2013 at 1:12
  • @kurtm - any better method on BSD? Also is pwdx there?
    – slm
    Oct 10, 2013 at 1:17
9

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.

4

For macOS: If you know the PID and want to get the exact file/directory (no other information) use:

lsof -a -p 1234 -d cwd -F n | tail -1 | cut -c2-

-a: Tell lsof to join using AND instead of OR for the -p and -d options below
-p: pass in process id (pid) 1234
-d: only include the file descriptor, cwd
-F: Specify the fields to output (choose from the list of characters here)

The n character passed to -F option outputs 3 things separated by newlines. We only want the last one (the current working directory). We pipe the output into tail to get the last line then pipe it into cut to trim the first character.

1

Based @Gilles answer..

if you know PID of your process.. for Mac OSX and Linux use:

lsof -p PID | awk '$4=="cwd" {print $9}'

to get working dir of process..

1
  • lsof: WARNING: can't stat() tracefs file system /sys/kernel/debug/tracing Output information may be incomplete. Anyone else get this? Apr 26, 2020 at 5:42
1

On FreeBSD you can use:

procstat -f <PID> | grep cwd

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.