Różnica między „nie znaleziono polecenia” a „nie ma takiego pliku lub katalogu”?

33

Na przykład:

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

Co za różnica? W obu przypadkach, nodea foosą nieprawidłowe polecenia, ale wydaje się, Unix po prostu nie może znaleźć nodepliku binarnego? Podczas odinstalowywania programu, na przykład node, istnieje sposób, aby to wyczyścić, aby uzyskać

$ node
-bash: node: command not found

EDYTOWAĆ:

Wyniki z typepolecenia:

$ type node
node is hashed (/usr/local/bin/node)
$ type foo
-bash: type: foo: not found
gwg
źródło
Czy możesz zaktualizować swoje pytanie o dane wyjściowe obu ( type nodei type fooprawdopodobnie tylko pierwszy naprawdę jest pomocny).
Eric Renouf,
@EricRenouf, dobra, zrobiłem to.
gwg
2
Prawdopodobnie „węzeł” jest dowiązaniem symbolicznym z / usr / bin / node -> / usr / local / bin / node i ten ostatni nie jest dostępny, stąd błąd, który sugerowałby, że / usr / local / bin / node został usunięty po utworzeniu dowiązania symbolicznego.
podobnie jak

Odpowiedzi:

59

To dlatego, że bashzapamiętałeś lokalizację polecenia, przechowuj ją w tabeli skrótów .

Po odinstalowaniu nodetabela skrótów nie jest czyszczona, bashnadal myśli , że nodejest /usr/local/bin/node, pomijając PATHwyszukiwanie i dzwoniąc /usr/local/bin/nodebezpośrednio, używając execve(). Ponieważ kiedy nodejuż go nie ma, execve()zwraca ENOENTbłąd, co oznacza, że ​​nie ma takiego pliku lub katalogu, bashzgłosił ten błąd.

W bashmożesz usunąć wpis z tabeli skrótów:

hash -d node

lub usuń całą tablicę skrótów ( działa we wszystkich powłokach POSIX ):

hash -r
Cuonglm
źródło
2
Zauważ, że nie musi /usr/local/bin/nodetego brakować; jeśli plik ten jest dynamicznie połączonym plikiem wykonywalnym i brakuje jednej z zależności, pojawi się ten sam komunikat „Brak takiego pliku lub katalogu”. To może doprowadzić cię do szaleństwa, dopóki nie spróbujesz lddtego pliku.
Guntram Blohm wspiera Monikę
@GuntramBlohm, ale na niektórych dystrybucjach Linuksa bash jest załatany, aby drukować bardziej zrozumiałe komunikaty o błędach, takie jak progname: error while loading shared libraries: badLib.so.1: cannot open shared object file: No such file or directory(lub może nie być bash w tym konkretnym przypadku, ale ld-linux.so).
Ruslan
@Ruslan Z mojego doświadczenia wynika, że ​​pojawia się „błąd podczas ładowania bibliotek współdzielonych”, jeśli brakuje „zwykłej” biblioteki współdzielonej, i niewytłumaczalny „brak takiego pliku lub katalogu”, jeśli brakuje samego dynamicznego linkera . Ma to sens, gdy uświadomisz sobie, że pierwszy przypadek jest wykrywany przez dynamiczny linker, podczas gdy drugi przypadek jest wykrywany przez jądro, i znacznie łatwiej jest dynamicznemu linkerowi wydrukować pomocną wiadomość ( execvepisanie do stderr jako efekt uboczny w przypadku awarii prawdopodobnie naruszyłoby POSIX czy coś takiego
zwolnij
@zwol ah, racja, właśnie po to niektóre łatki z dystrybucji Distros (np. CentOS). Taka łatana wersja następnie drukuje błędy takie jak /lib/ld-linux.so.2: bad ELF interpreter: No such file or directory.
Ruslan
-6

W systemie Ubuntu Linux 16.04 znalazłem, że „Brak takiego pliku lub katalogu” oznacza, że ​​musisz zmienić bieżący katalog roboczy, a „nie znaleziono polecenia” oznacza, że ​​musisz użyć apt-get install xxxyyy_zzz, aby rozwiązać problem.

Szczery
źródło
10
Jeśli twój cwd ma jakikolwiek wpływ na to, co zostanie znalezione, lub nie (chyba że użyjesz przedrostka ./), twoja ŚCIEŻKA jest skonfigurowana w dość niebezpieczny sposób. A nie znaleziono polecenia nie zawsze jest problemem, który chcesz naprawić :)
rackandboneman,