./ vs . do uruchamiania programów pod terminalem

13

Potrzebuję wyjaśnień dotyczących sposobu uruchamiania plików wykonywalnych pod terminalem. To może być kiepskie pytanie, ale jaka jest różnica między uruchomieniem pliku wykonywalnego za pomocą ./an_executablei . an_executable(załóżmy, że znajdujemy się w katalogu, w którym znajduje się plik wykonywalny )

Wiem już, że ten pierwszy sprawia, że ​​powłoka szuka w pliku bieżącym ( .) polecenia do wykonania, ale dlaczego nie jest /potrzebny po .użyciu drugiej wersji?

Z góry dziękuję.

zipzap
źródło
Zobacz także askubuntu.com/q/182012/26972
ysap

Odpowiedzi:

22

. executableSkładnia nie współpracuje z byle wykonywalny (lub nie?). Zamiast tego jest to alias dla sourcewbudowanej wersji bash . Różnica dotyczy głównie skryptów bash, a prawda jest taka, że ​​są to zupełnie różne rzeczy :)

./executableprosi o uruchomienie pliku wykonywalnego „normalnie”. ./jest względnym odniesieniem do bieżącej ścieżki. Dzięki temu powłoka (bash) nie będzie próbowała zlokalizować pliku wykonywalnego w katalogu w swoim katalogu $PATH(co zrobiłoby to, gdyby komenda nie określiła ścieżki). Powodem, dla którego nie możesz tego zrobić, executablejest bezpieczeństwo; wyobraź sobie, że rozpakowałeś pobrane archiwum, które zawiera złośliwą wersję ls. Gdyby działał bezpośrednio z bieżącego katalogu, uruchomiłbyś tę wersję, nie zdając sobie z tego sprawy.

Z drugiej strony . executablemówi „źródłowy plik o nazwie executable”. Ponieważ bezpośrednio nazywasz ten plik i tak naprawdę nie musi to być plik wykonywalny, ograniczenie bezpieczeństwa dla $ PATH nie ma zastosowania. Sourcing będzie „uruchamiał” (lub wydaje się, że uruchamia) skrypty powłoki. Co to robi:

   source filename [arguments]
          Read and execute commands from filename  in  the  current  shell
          environment  and return the exit status of the last command exe‐
          cuted from filename.

Więc ... Jaka jest naprawdę różnica między wykonywaniem a pozyskiwaniem? Zakładając ten sam skrypt powłoki, wykonanie go ( ./script) spowoduje odrodzenie nowej powłoki, uruchomienie skryptu wewnątrz tej powłoki, a kiedy skrypt zakończy działanie, zamknij tę powłokę i powróć do powłoki macierzystej. W efekcie rozpocznie nowy bashproces wykonywania skryptu).

( . script) spowoduje, że bieżąca powłoka będzie czytać polecenia z pliku tak, jakby były wpisywane w wierszu poleceń. Nie pojawiła się nowa powłoka.

Bardzo łatwym sposobem na sprawdzenie, jak się to zachowuje, jest napisanie skryptu zawierającego tylko exit. Jeśli ./scriptnie, nic nie wydaje się stało, to dlatego, że nowy proces powłoki rozpoczyna się, gdy exitwychodzi dowodzenia, że nowa powłoka i aktualna powłoka jest nienaruszona.

Jeśli tak . script, bieżący terminal zostanie zamknięty, ponieważ exitpolecenie działa w bieżącej powłoce. Odpowiada to wpisywaniu exitw wierszu polecenia.

roadmr
źródło
Rzeczywiście miałem do czynienia ze skryptem powłoki, gdy zauważyłem to zachowanie. Dziękuję bardzo, to była odpowiedź, której potrzebowałem. :)
zipzap
kolejne pytanie (jeśli nie masz nic przeciwko): jeśli mój skrypt zawiera tylko kilka prostych wiadomości z echo i uruchamiam go z ./script, to dlaczego mogę zobaczyć wiadomości w powłoce nadrzędnej, jeśli podpowłoka się zamknie jak tylko skończy się egzekucja?
zipzap
2
Ponieważ podpowłoka jest osobnym procesem , wykorzystuje ten sam terminal, co powłoka wywołująca. Jest podobny do tego, w jaki sposób nadal widzisz lsdane wyjściowe: wpisujesz polecenie, uruchamia się, pokazuje dane wyjściowe, a następnie się kończy, ale dane wyjściowe pozostają w terminalu.
roadmr
2
Nie myl powłoki z terminalem; to różne rzeczy. Otwórz terminal, a wiersz polecenia zostanie wydany przez bashdziałającą w nim powłokę. Jeśli wpiszesz bash, uruchomisz kolejną powłokę; do pierwszej powłoki, to tylko program do uruchomienia. Jeśli wpiszesz exit, zamkniesz ostatnią powłokę, którą uruchomiłeś, ale nadal będziesz w pierwszej powłoce (tej od momentu uruchomienia terminalu). Znowu to wszystko dzieje się w tym samym terminalu.
roadmr
1
@DavidZ Wspomniałem o tym :) „Sourcing będzie tylko„ uruchamiał ”(lub wydaje się, że uruchamia) skrypty powłoki.”
roadmr