/ proc / self é açúcar sintático. É um atalho para contatenar / proc / e o resultado do syscall getpid () (acessível no bash como o metavariável $$). Pode ser confuso, no entanto, no caso de scripts de shell, pois muitas das instruções invocam outros processos, completos com os próprios PIDs ... PIDs que se referem, na maioria das vezes, a processos mortos. Considerar:
root@vps01:~# ls -l /proc/self/fd
total 0
lrwx------ 1 root root 64 Jan 1 01:51 0 -> /dev/pts/0
lrwx------ 1 root root 64 Jan 1 01:51 1 -> /dev/pts/0
lrwx------ 1 root root 64 Jan 1 01:51 2 -> /dev/pts/0
lr-x------ 1 root root 64 Jan 1 01:51 3 -> /proc/26562/fd
root@vps01:~# echo $$
593
'/ bin / ls' avaliará o caminho para o diretório, resolvendo-o como / proc / 26563, pois esse é o PID do processo - o recém-criado processo / bin / ls - que lê o conteúdo do diretório. Porém, no momento em que o próximo processo no pipeline, no caso de scripts de shell, ou no momento em que o prompt retornar, no caso de um shell interativo, o caminho não existe mais e a saída de informações se refere a um processo inexistente.
Isso se aplica apenas a comandos externos, no entanto (aqueles que são arquivos de programas executáveis reais, em vez de incorporados ao próprio shell). Portanto, você obterá resultados diferentes se, digamos, usar globbing de nome de arquivo para obter uma lista do conteúdo do diretório, em vez de passar o nome do caminho para o processo externo / bin / ls:
root@vps01:~# ls /proc/self/fd
0 1 2 3
root@vps01:~/specs# echo /proc/self/fd/*
/proc/self/fd/0 /proc/self/fd/1 /proc/self/fd/2 /proc/self/fd/255 /proc/self/fd/3
Na primeira linha, o shell gerou um novo processo, '/ bin / ls', via syscall exec (), passando "/ proc / self / fd" como argv [1]. '/ bin / ls', por sua vez, abriu o diretório / proc / self / fd e leu e depois imprimiu seu conteúdo conforme iterava sobre eles.
A segunda linha, no entanto, usa glob () nos bastidores para expandir a lista de nomes de arquivos; estes são passados como uma matriz de strings para eco. (Geralmente implementado como um comando interno, mas geralmente também existe um binário / bin / echo ... mas essa parte é realmente irrelevante, pois o echo está apenas lidando com cadeias de caracteres que nunca alimenta qualquer syscall relacionada aos nomes de caminho.)
Agora, considere o seguinte caso:
root@vps01:~# cd /proc/self/fd
root@vps01:~# ls
0 1 2 255
Aqui, o shell, o processo pai de / bin / ls, transformou um subdiretório de / proc / self em seu diretório atual . Assim, nomes de caminho relativos são avaliados a partir de sua perspectiva. Meu melhor palpite é que isso esteja relacionado à semântica do arquivo POSIX, na qual você pode criar vários links físicos para um arquivo, incluindo qualquer descritor de arquivo aberto. Portanto, desta vez, / bin / ls se comporta de maneira semelhante a echo / proc / $$ / fd / *.
/proc/self
, é claro.