Czy ./ (kropka) jest poleceniem?


16

Rdzeń pytania:

Pytanie pojawiło się, gdy nie mogłem zainstalować oprogramowania, więc szczerze pytam o ./, ponieważ nie wiedziałem o tym, a wyjściowe polecenie „nie znaleziono polecenia” myliło mnie co do tego, czym właściwie było to polecenie.

Kontekst:

Chciałbym zainstalować plik truecrypt-7.2-setup-x86.

Instrukcje mówią, aby użyć polecenia:

sudo ./truecrypt-7.2-setup-x86

Ale wynik jest następujący:

sudo: ./truecrypt-7.2-setup-x86: command not found

AKTUALIZACJA: dla kompletności, w teście byłem w folderze plików, ale jeszcze nie uczyniłem pliku wykonywalnym (chmod + x).


1
./Część komendy mówi „Spójrz w bieżącym katalogu i wykonać polecenia«truecrypt-7.2-setup-x86»stąd”. Musisz uruchomić to polecenie z katalogu, w którym rozpakowałeś plik.
Charles Green

2
@Videonauth - Nie bardzo, osobiście nie sądzę, aby wzrósł do poziomu odpowiedzi.
Charles Green

1
@Zanna Przetestowałem skrypt bez uprawnień wykonywania, a zgłoszonym błędem był błąd braku uprawnień, a nie znaleziono polecenia.
Charles Green

2
@ubuntubu OK, bardzo dobrze, przeprowadziłeś się do katalogu - dobrze. Mały komentarz do edycji. Polecenie powinno być chmod +x, chmod -xwręcz przeciwnie - usuwa uprawnienia do wykonywania
Sergiy Kolodyazhnyy

4
Tytuł pytania jest zupełnie inny niż treść; może to powinno zostać naprawione?
David Z

Odpowiedzi:


24

./nie jest rozkazem. Poleceniem jest ./truecrypt-7.2-setup-x86.

Twoja powłoka i programy sudobędą traktować polecenie jako nazwę ścieżki, jeśli zawiera co najmniej jeden /znak. Ponieważ .reprezentuje katalog, w którym aktualnie się znajdujesz, ./truecrypt-7.2-setup-x86nazwa pliku truecrypt-7.2-setup-x86w bieżącym katalogu. Jeśli nie ma takiego pliku lub plik istnieje, ale nie można go uruchomić, pojawi się komunikat o błędzie.

Kiedy polecenie nie zawiera ukośnika, $PATHwyszukiwane są katalogi wymienione w , jak mówi Sergiy Kolodyazhnyy . Bieżący katalog nie jest automatycznie przeszukiwane - i to nie zaleca się umieścić .w $PATH. W ten sposób nie uruchamiasz przypadkowo rzeczy, których nie spodziewałeś się uruchomić, ponieważ zdarzyło się, że masz cdd do katalogu, który je zawiera.

Zapisywanie ./przed nazwą pliku wykonywalnego w bieżącym katalogu jest powszechnym sposobem jego uruchomienia, ale tak naprawdę nie jest to specjalna składnia. Na przykład, jeśli coś pomieszałeś $PATHi musisz uruchomić polecenie ls, możesz napisać /bin/ls. .W takim przypadku lub ogólnie nie jest to konieczne; potrzebujemy /gdzieś w nazwie ścieżki, co oznacza, że ​​masz na myśli, że jest to ścieżka.

Ponieważ .zawsze jest to katalog bieżący i /jest tylko separatorem katalogu, pierwszą rzeczą do zrobienia jest sprawdzenie, czy plik, który podałeś, naprawdę istnieje w bieżącym katalogu. (Jeśli tak, sprawdź jego uprawnienia , jak wyjaśnia Charles Green . Ale jeśli wyodrębniłeś plik z archiwum, zwykle będzie on miał uprawnienia do wykonywania, jeśli ma być uruchomiony).


21

Część polecenia ./ mówi „Szukaj w bieżącym katalogu i wykonaj polecenie„ truecrypt-7.2-setup-x86 ”stąd”. Musisz uruchomić to polecenie z katalogu, w którym rozpakowałeś plik.

Można to przetestować: W tym samym oknie terminala, w którym próbujesz wykonać polecenie, wpisz polecenie ls -l true*- jeśli plik jest obecny w bieżącym katalogu roboczym, zostanie wyświetlona lista pokazująca plik (i kilka dodatkowych informacji).

Jak zauważyła Zanna w komentarzach, twój plik może nie mieć uprawnień do wykonywania - można to łatwo naprawić. Jako przypadek testowy pokazuje mój katalog

chick@dad:~/test$ ls -l
total 4
-rw-r--r-- 1 chick chick 788 Oct 27 06:15 rFullBack
chick@dad:~/test$

a plik „rFullBack” wymienia „-rw-” jako moje uprawnienie do odczytu i zapisu pliku. Mogę wykonać polecenie, chmod +x rFullBacka lista katalogów zmieni się na

chick@dad:~/test$ ls -l
total 4
-rwxr-xr-x 1 chick chick 788 Oct 27 06:15 rFullBack
chick@dad:~/test$

Tam moje uprawnienia są teraz „-rwx”, co oznacza, że ​​mogę wykonać plik.


Krótko mówiąc, jeśli plik istnieje w twoim katalogu

uruchom polecenie

chmod +x ./truecrypt-7.2-setup-x86

a następnie polecenie

sudo ./truecrypt-7.2-setup-x86

1
Nie do końca. Wymienia rw-jako twoje pozwolenie - -przed ustawieniem [gu] id i lepkich bitów.
Duncan X Simpson

@DuncanXSimpson Dzięki - zaktualizowałem trochę opis uprawnień, ale zignoruję setguid i lepkie fragmenty tej odpowiedzi!
Charles Green

8

Jak działa wywoływanie poleceń w powłoce

Nie, to nie jest polecenie. Sposób, w jaki działają powłoki, polega na wpisaniu wiersza tekstu. Pierwsze słowo będzie traktowane jako polecenie, a jeśli polecenie nie jest jednym z poleceń wbudowanych w powłokę, powłoka sprawdzi wszystkie lokalizacje wymienione w PATH zmiennej środowiskowej .

Co się stanie, jeśli polecenie, które chcesz uruchomić, znajduje się w tym samym katalogu, w którym aktualnie się znajdujesz, ale ten katalog nie znajduje się na liście PATHkatalogów? Właśnie wtedy musisz użyć ./. Jest to dokładnie to samo co robisz /bin/bash- mówisz powłoce, gdzie znajduje się żądane polecenie, pełną ścieżkę do niego. A w przypadku ./ mówisz do powłoki „zajrzyj do tego katalogu”. Tak ważną częścią jest to, że musisz znajdować się w tym samym katalogu, w którym znajduje się plik.

Oczywiście, aby faktycznie uruchomić plik wykonywalny, musi on mieć ustawiony bit pliku wykonywalnego, więc musisz to zrobić chmod +x ./my_file.

Więc ważne kroki:

  1. cd gdzie zapisałeś plik; jeśli jest w ~/Downloadsśrodku, tocd ~/Downloads
  2. Uruchom chmod +x ./truecrypt-7.2-setup-x86, mówi „zrób plik truecrypt-7.2-setup-x86, który jest w tym katalogu wykonywalny”
  3. A teraz rób sudo ./truecrypt-7.2-setup-x86

Zauważ, że użycie ./nie jest przypadkowym zachowaniem, ale w rzeczywistości jest standardem określonym przez standard Przenośnego Systemu Operacyjnego (znany również jako POSIX) , w szczególności zobacz sekcję „Wyszukiwanie i wykonywanie poleceń”.

Odtworzenie błędu

$ # my script is in ~/Downloads folder
$ stat -c "%n" /home/xieerqi/Downloads/my_script.sh                         
/home/xieerqi/Downloads/my_script.sh
$ # if I run sudo ./my_script.sh, we get an error
$ sudo ./my_script.sh
[sudo] password for xieerqi: 
sudo: ./my_script.sh: command not found
$ # of course the command not found because file is not in ./, not in this dir
$ # this is not  sudo's problem
$ # but sudo does indeed show the same error even if you're in same directory
$ cd ./Downloads/                                                                                                                                                      
$ sudo ./my_script.sh                                                                                                                                                  
[sudo] password for xieerqi: 
sudo: ./my_script.sh: command not found

UWAGA : podany przez komunikat o błędzie sudojest oczywiście mylący, więc należy o tym pamiętać; należy jednak pamiętać, że nie było to sedno pytania zadawanego przez OP.

Dokumentacja i referencje

Z bashpodręcznika 4.3 sekcja „WYKONYWANIE POLECEŃ”:

Jeśli nazwa nie jest ani funkcją powłoki, ani wbudowanym i nie zawiera ukośników, bash przeszukuje każdy element PATH w poszukiwaniu katalogu zawierającego plik wykonywalny o tej nazwie.

Od Dlaczego potrzebujesz ./ (kropka-ukośnik) przed nazwą skryptu, aby uruchomić go w bash? :

Działa z ./, ponieważ POSIX określa, że nazwa polecenia zawierająca / będzie używana bezpośrednio jako nazwa pliku, co pomija wyszukiwanie w $ PATH. Możesz użyć pełnej ścieżki dla tego samego efektu, ale ./ jest krótszy i łatwiejszy do napisania.


W rzeczywistości sudowyniki są mylące. Jeśli spróbujesz to samo bez sudodostaniesz kolejny błąd z bash: Permission denied. I słusznie, ponieważ nie dałeś skryptowi pozwolenia na wykonanie (przez chmod +x).
Ruslan

@ Ruslan fakt, że sudodane wyjściowe wprowadzają w błąd, jest prawdą, ale taki właśnie błąd się pojawia. Może to być coś, co należy zgłosić programistom i pozwolić im to naprawić. Nie jest to jednak sedno dyskusji - musieliśmy ustalić, co PO zrobił, aby spowodować taki błąd, i poprowadzić ich właściwą ścieżką. Niezależnie od tego, czy jest to wprowadzające w błąd - nie o to tutaj chodzi.
Sergiy Kolodyazhnyy

Z drugiej strony nie jest to dokładnie to samo, co używanie /bin/bash: nie pozwala na wykonanie skryptu, na który nie masz uprawnień do wykonywania. Kiedy poprzedzasz nazwę skryptu, liczy /bin/bashsię fakt, że /bin/bashmożna go wykonać , ponieważ jest to wykonywane polecenie. Gdy tego nie zrobisz, sam skrypt jest wykonywany, co z kolei prowadzi do #!wywołania twojej bieżącej powłoki lub wywołania czegokolwiek w górnym wierszu
Monty Harder

@MontyHarder /bin/bashjest tutaj tylko przykładem. Fakt, że dzwonimy /bin/bashi ./script.sh podając ścieżkę do wykonywanej rzeczy - to samo. Wstępne wykonywanie skryptu z bash script.shlub /bin/bash script.shjest zupełnie innym tematem, w którym uruchamiasz plik wykonywalny i przekazujesz mu skrypt jako argument - który, nawiasem mówiąc, może się zepsuć, jeśli składnia jest napisana dla czegoś innego niż wywoływana powłoka, powiedzmy csh. /bin/bashjest wykonywalny w porządku, ale faktem jest, że nadal określasz pełną ścieżkę do niego.
Sergiy Kolodyazhnyy

2
@SergiyKolodyazhnyy Wstępne zastępowanie nazwy skryptu za pomocą, /bin/basha nawet po prostu, bashjest również częstym sposobem rozwiązania problemu braku uprawnień do wykonywania skryptu. Określenie pełnej ścieżki skryptu nie rozwiązuje tego problemu. Tak /bin/bashjest szczególnie zły przykład w tym konkretnym przypadku.
Monty Harder
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.