'/ proc / $ PID / cwd': existe um equivalente POSIX?

7

O Linux tem um diretório /proc e um sistema de arquivos, que, até onde eu sei, não faz parte do POSIX. Em cada subdiretório /proc/$PID , é um link simbólico, cwd , apontando para o diretório de trabalho real do processo deste PID (o link cwd está sempre atualizado).

Este link simbólico é conveniente para alguns casos de uso, como trabalhar com shells distintas e trocar arquivos entre os dois shells (formalmente, seus diretórios de trabalho).

Existe uma maneira simples de obter algo semelhante, usando apenas o recurso POSIX?

Mais sobre a questão

Após um comentário, mais precisão: ele não precisa necessariamente ser um link e uma variável de ambiente lile $<PID>_CWD , seria muito bom também, embora no primeiro suspiro, eu não acredito que tal solução exista. Apenas tem que ser fácil de se referir (ex. Link simbólico ou variável de ambiente) e estar sempre atualizado a cada vez que o outro processo alterna seu diretório de trabalho.

A solução não precisa necessariamente ser POSIX, e o aspecto mais importante é a portabilidade, mas POSIX é certamente uma garantia.

    
por Hibou57 08.07.2014 / 15:24

3 respostas

5

Eu tenho uma solução que usa lsof . Ele não é instalado no BSD por padrão, portanto, se alguém quiser usá-lo no BSD, é necessário instalá-lo.

Crie um script de shell:

#!/bin/sh
lsof -p $1 | grep cwd | awk '{print $9}'

Copie-o para um diretório em seu caminho. Imprime o diretório de trabalho do PID dado no primeiro argumento, I.E.

$ script 1987
/home/enedil
    
por 08.07.2014 / 16:31
4

O POSIX não oferece muito em termos de obter informações sobre processos não relacionados. Há apenas ps , e não fornece informações sobre o diretório atual . As APIs de nível C não são melhores (na verdade, a maioria das informações recuperadas por ps só pode ser recuperada ao analisar sua saída¹).

Curiosamente, o POSIX oferece uma maneira portátil de fazer o contrário: dado um arquivo, você pode descobrir quais processos o abrem chamando fuser . O snippet a seguir lista os PIDs dos processos que possuem um diretório de trabalho específico:

fuser -f "$directory_name" 2>&1 | sed -e '$!d' -e 's/.*://' -e 's/  */\
/' | sed -n 's/c$//p'

Se você quiser informações sobre os processos de uma forma portável na prática, use lsof . O autor de lsof fez o trabalho de implementar todas as diferentes formas de recuperar informações sobre diferentes variantes unix.

Para navegação casual:

lsof -a -p "$pid" -d cwd

Para análise automatizada:

lsof -a -p "$pid" -d cwd -F n | sed -e '1d' -e '2s/^n//'

Observe que lsof substitui as novas linhas pela string \n .

Algumas variantes do Unix oferecem métodos que não exigem software de terceiros, mas esses métodos serão necessariamente específicos para cada variante. Em uma nota muito relacionada, consulte Portabilidade dos links do descritor de arquivo

¹ Alguns antigos unices tem ps setuid root e lendo a memória do kernel, então usar esse setuid binary foi a única maneira de obter esta informação.

    
por 08.07.2014 / 19:15
0

Eu contribuirei com minha própria resposta.

Uma opção, no contexto do shell interativo (a questão se concentra nesse contexto), poderia manter automaticamente um link para la /proc/$PID/cwd , usando a oportunidade de automação que o Bash fornece:

PROMPT_COMMAND="ln -sfT \$(pwd) ~/$LINK_NAME"

A opção f é necessária, pois o link será freqüentemente substituído. A opção T é necessária, caso contrário, parece que a opção f funciona corretamente.

Os reservatórios podem ser feitos cooperativos, usando isto em ex., ~/.bashrc :

if [ -v CWD_LINK_NAME ]; then
   PROMPT_COMMAND='ln -sfT "$(pwd)" "'$CWD_LINK_NAME'";'$PROMPT_COMMAND
   declare -r CWD_LINK_NAME
   function rm_cwd_link() {
      rm "$CWD_LINK_NAME"
   }
   trap rm_cwd_link EXIT
fi

Um shell ou um terminal pode ser executado com CWD_LINK_NAME definido para qualquer valor relevante. Ex. CWD_LINK_NAME="~/$SOME_ROLE_NAME" gnome-terminal

Outra alternativa é usar o mesmo conceito para rastrear o diretório de trabalho da pêra em uma variável, sendo esse rastreamento baseado em @ Gilles e @enedil contribuições:

PROMPT_COMMAND="PEAR_WD=\$(lsof -p $PID | awk '/cwd/{print \}')"

No entanto, isso é menos preciso e menos prático, embora ainda possa ser o único caminho para os casos raros em que o $PROMPT_COMMAND não pode ser definido no outro shell.

Sou a favor da primeira opção (ainda esperando antes de selecionar uma resposta, se houver outras contribuições por vir).

    
por 09.07.2014 / 13:45