O padrão de shell POSIX diz neste site
http://pubs.opengroup.org/onlinepubs/9699919799/
sobre como os shells usam PATH
para procurar executáveis:
"A lista deve ser pesquisada do começo ao fim, aplicando o nome do arquivo a cada prefixo, até que um arquivo executável com o nome especificado e as permissões de execução apropriadas seja encontrado."
Bem, não é assim que isso parece funcionar na implementação real do POSIX:
man which
diz:
"retorna os nomes de caminho dos arquivos (ou links) que seriam executados no ambiente atual, se seus argumentos fossem dados como comandos em um shell estritamente compatível com POSIX. Isso é feito pesquisando no PATH por arquivos executáveis que correspondem aos nomes dos argumentos. Não segue links simbólicos ".
OK, vamos olhar para esta situação:
$ pwd
/home/mark
$ echo $PATH
/home/mark/bin:
...
$ ls -l bin/foobar
lrwxrwxrwx 1 mark mark 18 Dec 12 22:51 bin/foobar -> /home/mark/foobar1
$ touch foobar1
$ which foobar
$ chmod a+x foobar1
$ which foobar
/home/mark/bin/foobar
OK, aqui está um link simbólico PATH
com o nome correto e é relatado ls
como sendo executável.
which
não olha nada, mas só está interessado no que aponta.
Isso apesar do fato de ambos man which
dizerem explicitamente que ele não segue links simbólicos (e, de fato, o vemos, porque which foobar
não imprime foobar1
), e também que a documentação do shell POSIX citada acima, nunca menciona os links simbólicos no PATH
algoritmo.
Então, which
as conchas existentes estão erradas ou não estou entendendo a documentação?
ESCLARECER:
Eu sei e posso explicar o comportamento existente. Minha pergunta não é "como isso funciona?". Que eu saiba.
Minha pergunta é sobre documentação: onde está meu erro em seguir a documentação que citei. Ou a documentação está errada?
MOTIVAÇÃO: Por que eu me importo?
Bem, eu sou um implementador. Implementadores diferentes têm requisitos diferentes. Para mim, o requisito é que a palavra do padrão POSIX atual DEVE ser seguida EXATAMENTE (ou, mais precisamente, o melhor que pode ser, porque o próprio padrão é um tanto incorreto). Como se fosse a palavra de Deus.
Agora, a redação padrão é bastante clara - os links simbólicos a seguir não são mencionados, onde em muitos outros lugares, é mencionado onde precisa ser feito. Então, neste caso, não.
No entanto, eu sempre verifiquei como dash
e me bash
comporte, apenas para ter certeza. Agora, é claro, também há um pequeno problema aqui, dash
mesmo que seja anunciado como POSIX, possui muitos pequenos bugs com conformidade com o POSIX. bash
, Ainda não encontrei nenhum bug com o POSIX, mas ... o bash não é realmente o POSIX, é muito mais do que isso.
Então aí está. É por isso que eu me importo.
$PATH
, não possui links simbólicos.
lstat(2)
), segui-los geralmente não é indicado. Por exemplo, a descrição open(2)
apenas menciona links simbólicos ao falar sobre o comportamento de O_CREAT | O_EXCL
. Não é necessário declarar que o arquivo de destino será aberto.
$PATH
can contém links simbólicos. Tentewhich sh
.