Descobrir o diretório de trabalho atual de um processo em execução?

168

Quais comandos podem ser usados ​​para descobrir o diretório de trabalho atual (CWD) de um processo em execução? Esses seriam comandos que você poderia usar externamente no processo.

slm
fonte

Respostas:

218

Existem três métodos que eu conheço:

pwdx

$ pwdx <PID>

lsof

$ lsof -p <PID> | grep cwd

/ proc

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

Exemplos

Digamos que temos esse processo.

$ pgrep nautilus
12136

Então, se usarmos pwdx:

$ pwdx 12136
12136: /home/saml

Ou você pode usar lsof:

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

Ou você pode cutucar diretamente no /proc:

$ readlink -e /proc/12136/cwd/
/home/saml
slm
fonte
2
Eu diria que / proc é canônico, com lsof sendo útil, mas pwdx é legal.
ChuckCottrill
3
Nem todos os Unices possuem /proc.
Reinierpost 10/10
Uma pergunta semelhante, mas diferente: unix.stackexchange.com/questions/173868/…
Sibbs Gambling
1
pwdxfunciona para mim.
Aroth
Aqui está uma maneira simples (da resposta de slm) pwdxpgrep <process-name>
Madhusoodan P
27

Presumo que você tenha o ID do processo pid. A maioria dos métodos na maioria dos sistemas exigirá que o shell do qual você está fazendo isso esteja sendo executado como o mesmo usuário que o processo de destino (ou raiz).

No Linux e Solaris e talvez em alguns outros sistemas do System V:

cd /proc/$pid/cwd && pwd

No Linux (exceto sistemas incorporados onde readlinknão está disponível), mas não no Solaris:

readlink /proc/$pid/cwd

Em praticamente qualquer variante unix, você pode usar lsof. Lembre-se de que, se houver uma nova linha, ela será impressa como \n(indistinguível da barra invertida seguida por n). Se você tiver sorte, poderá usar o segundo formulário, que silenciosamente engasga com todos os espaços em branco no nome do diretório.

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

Bônus: se você precisar fazer com que um processo altere seu diretório atual, poderá fazê-lo com um depurador. Isso é útil, por exemplo, para mover um programa de longa duração que não se importa com o diretório atual para fora de um diretório que você deseja remover. Nem todos os programas gostam de ter seu diretório atual alterado sob seus pés - por exemplo, um shell provavelmente trava.

#!/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
fonte
Toque agradável adicionando os detalhes sobre a mudança. Boa pepita para adicionar ao site!
slm
Você pode comentar sobre a onipresença de pwdxoutros Unixes?
slm
No OpenBSD, pelo menos, lsof relata apenas o ponto de montagem do CWD do processo.
kurtm
O @slm pwdxestá presente no Solaris desde o século 20, Linux desde meados dos anos 2000 (imitando o Solaris, diz a página de manual). Não está presente em nenhum outro AFAIK unix.
Gilles
@kurtm - algum método melhor para o BSD? Também pwdxexiste?
slm
9

Se o seu sistema possui /proc, você sempre pode:

readlink -e /proc/$$/cwd

Se você quiser descobrir o CWD de um processo diferente daquele em que está interessado, obviamente precisará substituir $$o PID do seu processo de interesse.

Joseph R.
fonte
0

Resposta baseada no @Gilles ..

se você conhece o PID do seu processo .. para Mac OSX e Linux, use:

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

para começar a trabalhar dir do processo ..

Dariusz Filipiak
fonte