Dlaczego używamy ./filename do wykonania pliku w systemie Linux?

Dlaczego nie po prostu wprowadź go tak jak inne polecenia gcc, ls itd …

Komentarze

  • Czy nie ' t pierwsza linia byłaby lepiej zapisana jako ” Dlaczego używamy ./command_name do wykonania polecenia w systemie Linux? ”
  • użytkownik15760, nie, ponieważ lubimy zadawać pytania wykrywalne w wyszukiwarkach i nie wszyscy, którzy mają to pytanie, są urodzonymi naturalnie ' nixsters (:

Answer

W systemie Linux, UNIX i pokrewnych systemach operacyjnych . oznacza bieżący katalog. Ponieważ chcesz uruchomić plik w bieżącym katalogu i w tym katalogu nie ma w Twoim $PATH, potrzebujesz bitu ./, aby wskazać powłoce, gdzie plik wykonywalny to. Tak więc ./foo oznacza uruchomienie pliku wykonywalnego o nazwie foo, który znajduje się w tym katalogu.

Możesz użyć type lub which , aby uzyskać pełną ścieżkę do wszelkich poleceń znajdujących się w $PATH.

Komentarze

  • Wykonywanie programów w bieżącym katalogu jest bardzo powszechne. Dlaczego nie ' nie szuka tam również powłoki? Najpierw wyszukuje w., A następnie w $ PATH.
  • istnieją również alias elementy, które mogą przeszkadzać, a nie tylko $PATH.
  • @Michael bezpieczeństwo i zdrowie psychiczne: jeśli najpierw wyszukałby w ., byłby to problem z bezpieczeństwem, Ty lub ktoś inny mógłby zastąpić Na przykład ls (prosty wirus / trojen: utwórz plik zip z plikiem wykonywalnym o nazwie ls, gdy ktoś przeszukuje, uruchamiają ten plik wykonywalny…). Jeśli przeszukiwał . jako ostatni, możesz spędzić dużo czasu na szaleństwie nie wiedząc dlaczego twój program nie działa (np. Tworzysz program o nazwie test, zamiast go uruchamiać program do testowania systemów. Który nie daje żadnych wyników).
  • @jcubic to ' to zły pomysł. Zobacz komentarz powyżej. W przeszłości przeszukiwania DOS w bieżącym katalogu i to zachowanie zostało przeniesione do cmd systemu Windows, co wprowadza wiele problemów związanych z bezpieczeństwem. MS naprawiło to w PowerShell i teraz musisz użyć. \ Aby uruchomić program w bieżącym katalogu
  • @ ctrl-alt-delor: Kiedy byłem na uniwersytecie pod koniec lat 80-tych ' s, była to powszechna (zabroniona) taktyka. Pisanie programu ” ls ” i pozostawienie go w folderze domowym na wypadek, gdyby ktoś przyszedł węszyć. Program został nazwany ” get shell ” IIRC. Próbowałaby uzyskać dane uwierzytelniające użytkownika uruchamiającego polecenie – a następnie może wydrukować fałszywą listę katalogów, aby pozostawić go nieświadomym.

Odpowiedź

Dosłowna odpowiedź jest taka, jak podali inni: ponieważ bieżący katalog nie znajduje się w twoim $PATH.

Ale dlaczego? Krótko mówiąc, chodzi o bezpieczeństwo. Jeśli szukasz katalogu domowego innej osoby (lub / tmp) i wpisz po prostu gcc lub ls, chcesz wiesz, że „używasz prawdziwej, a nie złośliwej wersji, którą napisał twój przyjaciel dowcipniś i która usuwa wszystkie twoje pliki. Innym przykładem może być test lub [, który może przesłonić te polecenia w skryptach powłoki, jeśli twoja powłoka nie ma ich jako wbudowanych.

Mając . jako ostatni wpis na twojej ścieżce jest nieco bezpieczniejszy, ale są też inne ataki, które to wykorzystują. Prostym sposobem jest wykorzystanie typowych literówek, takich jak sl lub ls-l. Lub znajdź typowe polecenie, które nie jest zainstalowane w tym systemie – na przykład vim, ponieważ administratorzy systemu mają ponadprzeciętne prawdopodobieństwo, że je wpiszą.

Czy to brzmi zbyt teoretycznie? w dużej mierze tak jest, ale z pewnością może się to zdarzyć w rzeczywistości, zwłaszcza w systemach z wieloma użytkownikami. W rzeczywistości tutaj jest przykład z tej witryny , w której administrator przełączył się do katalogu domowego użytkownika i znalazł ps być maskowane przez plik wykonywalny o tej nazwie.

Komentarze

  • Po prostu podaj bezwzględne ścieżki w PATH zmienna środowiskowa.

Odpowiedź

Jeśli masz na myśli, dlaczego potrzebujesz./ na początku – to dlatego, że (w przeciwieństwie do Windows), bieżący katalog nie jest domyślnie częścią ścieżki. Jeśli uruchomisz:

$ ls 

Twoja powłoka szuka ls w katalogach w zmiennej środowiskowej PATH (echo $PATH, aby go zobaczyć) i uruchamia pierwszy znaleziony plik wykonywalny o nazwie ls. Jeśli wpiszesz:

$ a.out 

powłoka zrobi to samo – ale prawdopodobnie nie znajdzie pliku wykonywalnego o nazwie a.out. Musisz powiedzieć powłoce gdzie a.out jest – czy znajduje się w bieżącym katalogu (.), to ścieżka to ./a.out.

Jeśli „pytasz, dlaczego to się nazywa „a.out”, to tylko domyślna nazwa pliku wyjściowego dla gcc. Możesz ją zmienić za pomocą argumentu wiersza poleceń -o. Na przykład:

$ gcc test.c -o test $ ./test 

Komentarze

  • Dzięki. Wątpię, dlaczego potrzebujesz ./ na początku …. Użyłem „.” (aby przejść do bieżącego katalogu), ale dlaczego ” / ” po tym?
  • / jest separatorem ścieżek w Linuksie, więc używasz go do oddzielenia katalogu (.) od nazwy pliku (a.out). Bez niego masz .a.out, który jest prawidłowym nazwa pliku sama w sobie. (Spróbuj touch .a.out; ls -lA, aby to zobaczyć).
  • tak określasz ścieżka w systemie Unix, <dir>/<file>, więc w zasadzie mówisz o wykonaniu pliku w bieżącym katalogu, na co wskazuje ./test
  • Red Hat Linux 9? Czas na aktualizację!
  • W systemie Windows 10 PowerShell jest teraz domyślną powłoką i wymaga również ./, aby uruchomić plik wykonywalny w bieżącej ścieżce

Odpowiedź

Możesz spróbować dodać :. do zmiennej $ PATH.

Spróbuj ALT + F2 i wpisz: gksudo gedit /etc/environment jeśli używasz Linuksa / GTK (to masz, jeśli używasz Ubuntu).

JEDNAK, Zdecydowanie odradzam tego robić. Jest źle, źle, źle i źle.

Wiesz, takie rzeczy działają od 1970 roku. Jest powód, dla którego bieżący katalog nie jest uwzględniony w $ PATH.

. to bieżący katalog

.something byłby plikiem ukrytym (wpisz „ALT +”, aby pojawiają się w Nautilusie lub spróbuj „ls -la„.

./someProgram.sh jest tym, co wpisujesz, aby URUCHOMIĆ plik wykonywalny jakiśProgram .sh w bieżącym katalogu.

.somethingElse oznaczałoby, że masz ukryty plik wykonywalny w bieżącym katalogu, co jest złym pomysłem.

Odpowiedź

Bardziej kompletna reguła to w rzeczywistości: jeśli jakikolwiek ukośnik / znajduje się na ścieżce, nie szukaj” t PATH

Zanim przejdziemy do uzasadnienie, powinieneś najpierw wiedzieć o tym fakcie: uruchamianie jednego z:

bin/someprog 

lub:

lub:

cd bin ./myexec 

wykonaj bin/someprog bez wyszukiwania PATH z dokładnie tego samego powodu: wszystkie bin/someprog, /bin/someprog i ./someprog mają w sobie ukośnik /.

someprog sam nie ma ukośnika /, dlatego wyszukuje tylko w PATH.

POSIX 7 określa tę regułę pod adresem: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01_01

PATH

[…] Jeśli poszukiwana nazwa ścieżki zawiera <slash>, przeszukiwanie prefiksów ścieżki nie będzie przeprowadzane .

Uzasadnienie dla / POSIX PATH

Załóżmy, że działa:

someprog 

wyszukałoby:

  • najpierw względem CWD
  • względne do PATH po

Następnie, jeśli chcesz uruchomić /bin/someprog ze swojej dystrybucji, a zrobiłeś:

someprog 

czasami działało, ale w innych nie, ponieważ możesz być w katalogu, który zawiera inny niepowiązany program someprog.

Dlatego wkrótce dowiesz się, że nie jest to wiarygodne i zawsze będziesz używać ścieżki bezwzględne, gdy chcesz używać PATH, co jest sprzeczne z celem PATH.

Dlatego też posiadanie ścieżek względnych w PATH jest naprawdę złym pomysłem. Patrzę na Ciebie , node_modules/bin .

I odwrotnie, załóżmy, że uruchomienie:

./someprog 

spowoduje wyszukanie:

  • najpierw względem PATH
  • względne w stosunku do CWD po

Następnie, jeśli właśnie pobrałeś skrypt someprog z repozytorium git i chciałeś go uruchomić z CWD, nigdy nie byłbyś pewien, że to jest rzeczywisty program, który by działał, ponieważ być może twoja dystrybucja ma:

/bin/someprog 

, który jest w Tobie ŚCIEŻKA z jakiś pakiet, który zainstalowałeś po wypiciu zbyt dużej ilości alkoholu po Bożym Narodzeniu w zeszłym roku.

Dlatego po raz kolejny będziesz zmuszony zawsze uruchamiać lokalne skrypty w stosunku do CWD z pełnymi ścieżkami, aby wiedzieć, co uruchamiasz:

"$(pwd)/someprog" 

, co również byłoby bardzo irytujące.

Inna zasada, która mogłaby Cię wymyślić, to:

ścieżki względne używają tylko PATH, ścieżki bezwzględne tylko CWD

ale po raz kolejny zmusza to użytkowników do zawsze używaj abso lute ścieżki dla skryptów innych niż PATH z "$(pwd)/someprog".

/ reguła wyszukiwania ścieżki oferuje łatwe do zapamiętania rozwiązanie do problemu:

  • ukośnik: nie używaj PATH
  • bez ukośnika: używaj tylko PATH

co sprawia, że zawsze łatwo zorientujesz się, co uruchamiasz, polegając na fakcie, że pliki w bieżącym katalogu można wyrazić jako ./somefile lub somefile, więc nadaje to szczególne znaczenie jednemu z nich.

Czasami jest nieco irytujące, że nie można wyszukiwać dla some/prog w stosunku do PATH, ale nie widzę rozsądniejszego rozwiązania tego problemu.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *