Узнать текущий рабочий каталог запущенного процесса?

168

Какие команды можно использовать, чтобы узнать текущий рабочий каталог (CWD) запущенного процесса? Это будут команды, которые вы можете использовать извне из процесса.

SLM
источник

Ответы:

218

Есть 3 метода, о которых я знаю:

pwdx

$ pwdx <PID>

Lsof

$ lsof -p <PID> | grep cwd

/ Proc

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

Примеры

Скажем, у нас есть этот процесс.

$ pgrep nautilus
12136

Тогда, если мы используем pwdx:

$ pwdx 12136
12136: /home/saml

Или вы можете использовать lsof:

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

Или вы можете тыкать прямо в /proc:

$ readlink -e /proc/12136/cwd/
/home/saml
SLM
источник
2
Я бы сказал, что / proc является каноническим, с lsof полезным, но pwdx - это круто.
ChuckCottrill
3
Не все союзы имеют /proc.
reinierpost
Аналогичный, но другой вопрос: unix.stackexchange.com/questions/173868/…
Sibbs Gambling
1
pwdxработает для меня.
Аромат
Вот простой способ (из ответа СЛМ) pwdxpgrep <process-name>
Madhusoodan P
27

Я предполагаю, что у вас есть идентификатор процесса в pid. Большинство методов в большинстве систем требуют, чтобы оболочка, из которой вы делаете это, работала с тем же пользователем, что и целевой процесс (или root).

В Linux и Solaris и, возможно, в некоторых других версиях System V:

cd /proc/$pid/cwd && pwd

В Linux (кроме встроенных систем, где readlinkнет), но не в Solaris:

readlink /proc/$pid/cwd

Вы можете использовать практически любой вариант Unix lsof. Помните, что если есть новая строка, она будет напечатана как \n(неотличимая от обратной косой черты, за которой следует n). Если вам повезет, вы можете использовать вторую форму, которая беззвучно душит все пробелы в имени каталога.

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

Бонус: если вам нужно заставить процесс изменить свой текущий каталог, вы можете сделать это с помощью отладчика. Это полезно, например, для перемещения долго работающей программы, которая не заботится о своем текущем каталоге, из каталога, который вы хотите удалить. Не все программы ценят изменение своего текущего каталога под ногами - например, оболочка может привести к сбою.

#!/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
жилль
источник
Приятное прикосновение, добавив детали о переезде. Добрый маленький самородок для добавления на сайт!
SLM
Можете ли вы прокомментировать вообще повсеместность pwdxдругих Unixes?
SLM
По крайней мере, в OpenBSD lsof сообщает только точку монтирования CWD процесса.
Куртм
@slm pwdxприсутствует в Solaris с 20-го века, Linux с середины 2000-х годов (имитируя Solaris, говорится на странице руководства). Нет на любом другом Unix AFAIK.
Жиль
@kurtm - есть ли лучший метод на BSD? Также pwdxесть?
SLM
9

Если ваша система имеет /proc, вы всегда можете сделать:

readlink -e /proc/$$/cwd

Если вы хотите узнать CWD из процесса, отличного от того, который вас интересует, вам, очевидно, нужно заменить $$PID вашего процесса, представляющего интерес.

Джозеф Р.
источник
0

На основании ответа @Gilles ..

если вы знаете PID вашего процесса .. для Mac OSX и Linux используйте:

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

получить рабочий каталог процесса ..

Дариуш Филипяк
источник