Znajdź aktualny katalog roboczy uruchomionego procesu?

167

Jakich poleceń można użyć, aby znaleźć bieżący katalog roboczy (CWD) uruchomionego procesu? Byłyby to polecenia, których można użyć zewnętrznie z procesu.

slm
źródło

Odpowiedzi:

217

Są 3 metody, o których wiem:

pwdx

$ pwdx <PID>

lsof

$ lsof -p <PID> | grep cwd

/ proc

$ readlink -e /proc/<PID>/cwd

Przykłady

Powiedzmy, że mamy ten proces.

$ pgrep nautilus
12136

Jeśli użyjemy pwdx:

$ pwdx 12136
12136: /home/saml

Lub możesz użyć lsof:

$ lsof -p 12136 | grep cwd
nautilus 12136 saml  cwd    DIR              253,2    32768  10354689 /home/saml

Lub możesz zaczepić bezpośrednio w /proc:

$ readlink -e /proc/12136/cwd/
/home/saml
slm
źródło
2
Powiedziałbym, że / proc jest kanoniczny, z lsof przydatnym, ale pwdx jest fajny.
ChuckCottrill 10.10.2013
3
Nie wszystkie jednorożce mają /proc.
reinierpost
Podobne, ale inne pytanie: unix.stackexchange.com/questions/173868/…
Sibbs Gambling
1
pwdxpracuje dla mnie.
aroth
Oto prosty sposób (z odpowiedzi SLM) pwdxpgrep <process-name>
Madhusoodan P
27

Zakładam, że masz identyfikator procesu pid. Większość metod w większości systemów wymaga, aby powłoka, z której to robisz, działała jako ten sam użytkownik co proces docelowy (lub root).

W systemach Linux i Solaris i być może w niektórych innych systemach Windows:

cd /proc/$pid/cwd && pwd

W systemie Linux (oprócz systemów wbudowanych, w których readlinknie jest dostępny), ale nie w systemie Solaris:

readlink /proc/$pid/cwd

Możesz użyć niemal każdego wariantu unixowego lsof. Uważaj, jeśli pojawi się nowa linia, zostanie wydrukowana jako \n(nie do odróżnienia od odwrotnego ukośnika, po której następuje n). Jeśli masz szczęście, możesz użyć drugiej formy, która cicho dusi wszystkie białe znaki w nazwie katalogu.

lsof -a -Fn -p $pid -d cwd | sed -e '1d' -e '2s/^n/'
lsof -p $pid | awk '$4=="cwd" {print $9}'

Bonus: jeśli chcesz spowodować, aby proces zmienił swój bieżący katalog, możesz to zrobić za pomocą debugera. Jest to przydatne na przykład do przeniesienia długo działającego programu, który nie dba o swój bieżący katalog, z katalogu, który chcesz usunąć. Nie wszystkie programy doceniają fakt, że ich bieżący katalog jest zmieniany pod stopami - na przykład powłoka może ulec awarii.

#!/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
Gilles
źródło
Miły akcent dodając szczegóły dotyczące przeprowadzki. Dobry mały samorodek do dodania do strony!
slm
Czy możesz w ogóle komentować wszechobecność pwdxinnych uniksów?
slm
Przynajmniej na OpenBSD, lsof zgłasza tylko punkt podłączenia CWD procesu.
kurtm 10.10.2013
@slm pwdxjest obecny na Solarisie od XX wieku, Linux od połowy 2000 roku (naśladuje Solaris, jak mówi strona podręcznika). Nie występuje na żadnym innym uniksowym AFAIK.
Gilles,
@kurtm - jakaś lepsza metoda na BSD? Też pwdxtam jest ?
slm
9

Jeśli twój system ma /proc, zawsze możesz:

readlink -e /proc/$$/cwd

Jeśli chcesz poznać CWD z innego procesu niż ten, który Cię interesuje, oczywiście musisz zastąpić $$PID swojego interesującego Cię procesu.

Joseph R.
źródło
0

Na podstawie odpowiedzi @Gilles ..

jeśli znasz PID swojego procesu .. dla Mac OSX i Linux użyj:

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

uzyskać działający katalog procesów ...

Dariusz Filipiak
źródło