Diferença entre "comando não encontrado" e "nenhum arquivo ou diretório"?

33

Por exemplo:

$ node
-bash: /usr/local/bin/node: No such file or directory
$ foo
-bash: foo: command not found

Qual é a diferença? Nos dois casos, nodee foosão comandos inválidos, mas parece que o Unix simplesmente não consegue encontrar o nodebinário? Ao desinstalar um programa, por exemplo node, existe uma maneira de limpar isso para que eu obtenha

$ node
-bash: node: command not found

EDITAR:

Resultados do typecomando:

$ type node
node is hashed (/usr/local/bin/node)
$ type foo
-bash: type: foo: not found
gwg
fonte
Você pode atualizar sua pergunta com a saída de ambos type nodee type foo(embora provavelmente apenas o primeiro seja realmente útil).
Eric Renouf
@EricRenouf, ok, eu fiz.
gwg
2
Provavelmente, 'node' é um link simbólico de / usr / bin / node -> / usr / local / bin / node e o último não está disponível, portanto, o erro, que sugere que / usr / local / bin / node foi excluído depois que o link simbólico foi criado.
likewhoa

Respostas:

59

Isso porque se bashlembrou do seu local de comando, armazene-o em uma tabela de hash .

Após a desinstalação node, a tabela de hash não é limpa, bashainda pensa que nodeestá /usr/local/bin/node, pulando a PATHpesquisa e chamando /usr/local/bin/nodediretamente, usando execve(). Como quando nodenão existe mais, execve()retorna ENOENTerro, significa que esse arquivo ou diretório não bashrelatou esse erro para você.

Em bash, você pode remover uma entrada da tabela de hash:

hash -d node

ou remova a tabela de hash inteira ( funciona em todos os shell POSIX ):

hash -r
cuonglm
fonte
2
Observe que não precisa estar /usr/local/bin/nodefaltando; se esse arquivo for um executável vinculado dinamicamente e uma das dependências estiver ausente, você receberá a mesma mensagem "Não existe esse arquivo ou diretório". Isso pode deixá-lo louco até você experimentar lddesse arquivo.
Guntram Blohm apoia Monica
@GuntramBlohm, mas em algumas distros do Linux o bash é corrigido para imprimir mensagens de erro mais compreensíveis, como progname: error while loading shared libraries: badLib.so.1: cannot open shared object file: No such file or directory(ou pode não ser o bash nesse caso específico, mas ld-linux.so).
Ruslan
@Ruslan Na minha experiência, você obtém o "erro ao carregar bibliotecas compartilhadas" se estiver faltando uma biblioteca compartilhada "comum" e o inexplicável "Não existe esse arquivo ou diretório" se estiver faltando o vinculador dinâmico . Isso faz sentido quando você percebe que o primeiro caso é detectado pelo vinculador dinâmico, enquanto o último caso é detectado pelo kernel, e é muito mais fácil para o vinculador dinâmico imprimir uma mensagem útil ( execvegravar no stderr como efeito colateral na falha provavelmente violar POSIX ou algo)
Zwol
@ zwol ah, certo, é para isso que algumas distros (por exemplo, CentOS) fazem o patch bash. Essa versão corrigida imprime erros como /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory.
Ruslan
-6

Eu descobri no Ubuntu Linux 16.04 que "Nenhum arquivo ou diretório" significa que você precisa mudar o diretório de trabalho atual, enquanto "comando não encontrado" significa que você deve usar o apt-get install xxxyyy_zzz para corrigir o problema.

Frank
fonte
10
Se o seu cwd tiver alguma influência sobre o que será encontrado ou não (a menos que você o prefixe com ./), seu PATH será configurado de uma maneira bastante insegura. E um comando não foi encontrado nem sempre é um problema que você quer corrigir :)
rackandboneman