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


168

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

Ответы:


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

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}'

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.