Linux oferuje polecenie, które służy do identyfikacji wykonywalnych plików binarnych uruchamianych przez powłokę po wydaniu odpowiedniego polecenia. W przypadku posiadania różnych wersji tego samego programu na komputerze, można skorzystać z tego narzędzia, aby sprawdzić, która wersja zostanie użyta przez powłokę.
Pliki binarne i ścieżki
Kiedy próbujesz uruchomić program czy polecenie w terminalu, powłoka (najczęściej Bash w nowoczesnych dystrybucjach) musi najpierw zlokalizować to polecenie i je uruchomić. Niektóre polecenia, jak cd, history czy pwd, są wbudowane w powłokę, co ułatwia ich lokalizację.
Jak jednak Bash odnajduje inne polecenia, programy oraz zewnętrzne pliki binarne? Otóż Bash korzysta z tzw. $PATH, który jest zbiorem ścieżek wskazujących na katalogi. Następnie przeszukuje te katalogi, aby znaleźć pliki wykonywalne odpowiadające wydawanym poleceniom. Gdy tylko odnajdzie odpowiedni plik, uruchamia go i przestaje dalsze poszukiwania.
Aby sprawdzić, jakie katalogi są zawarte w zmiennej środowiskowej $PATH, można użyć polecenia echo, jak pokazano poniżej:
echo $PATH
Wynik tego polecenia oddziela każdą ze ścieżek dwukropkami (:). Na naszym komputerze Bash przeszuka następujące katalogi w podanej kolejności:
/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/games
/usr/local/games
/snap/bin
W systemie plików istnieje wiele katalogów o nazwach /sbin i /bin, co może prowadzić do nieporozumień.
Zwróć uwagę na te ścieżki
Załóżmy, że mamy zaktualizowaną wersję programu o nazwie htg, znajdującą się w naszym bieżącym katalogu. Aby ją uruchomić, wystarczy wpisać:
./htg
Ten program jest prosty – wyświetla jedynie numer wersji, po czym kończy działanie. Nowa wersja to 1.2.138.
Aby uruchomić program znajdujący się w bieżącym katalogu roboczym, trzeba wpisać „./” przed nazwą pliku, aby Bash wiedział, gdzie go szukać.
Jeśli chcemy uruchomić ten program z dowolnego miejsca, musimy przenieść plik wykonywalny do katalogu /usr/bin, co sprawi, że Bash będzie mógł go znaleźć na ścieżce i uruchomić:
sudo mv htg /usr/bin
Teraz spróbujmy uruchomić program, wpisując:
htg
Program się uruchamia, ale to nie jest nasza nowa, zaktualizowana wersja. To raczej starsza wersja 1.2.105.
Które polecenie
Opisany powyżej problem ilustruje działanie polecenia which.
W tym przypadku użyjemy polecenia which, podając nazwę programu, który chcemy zbadać, jako argument:
which htg
Wynik pokazuje, że wersja htg została znaleziona w katalogu /usr/local/bin. Ponieważ ta lokalizacja występuje w ścieżce przed katalogiem, do którego przenieśliśmy zaktualizowaną wersję htg, Bash korzysta z wcześniejszej wersji programu.
which -a htg
Wynik pokazuje listę wszystkich dopasowań w katalogach znajdujących się w ścieżce.
Oto problem – w katalogu, który również znajduje się w ścieżce, znajduje się starsza wersja programu, a ten katalog jest przeszukiwany przed katalogiem, do którego wrzuciliśmy nową wersję programu.
Aby to zweryfikować, możemy wpisać następujące polecenia i uruchomić każdą wersję programu:
/usr/local/bin/htg
/usr/bin/htg
To wyjaśnia problem, a rozwiązanie jest proste.
Mamy w zasadzie dwie możliwości: możemy usunąć starą wersję z katalogu /usr/local/bin lub przenieść ją z /usr/bin do /usr/local/bin.
Analiza wyników
Wyniki mogą niekoniecznie oznaczać, że mamy dwa różne pliki binarne.
Przykładowo, używając polecenia which z opcją -a (all) i szukając wersji programu less:
which -a less
Wynik wskazuje na dwie lokalizacje, w których program less jest zainstalowany. Czy to możliwe? Dziwnie byłoby mieć dwie różne wersje (lub tę samą wersję w różnych lokalizacjach) less zainstalowane na komputerze z systemem Linux. Dlatego nie przyjmujmy tych wyników za pewnik. Zamiast tego przyjrzyjmy się dokładniej.
Możemy użyć opcji ls, -l (długa lista) i -h (czytelna dla człowieka), aby zobaczyć więcej szczegółów:
ls -lh /usr/bin/less
Rozmiar pliku wynosi jedynie dziewięć bajtów! Zdecydowanie nie jest to pełna wersja programu less.
Pierwszy znak w liście to „l”. Zwykły plik miałby na początku myślnik (-). Litera „l” oznacza, że jest to dowiązanie symboliczne. Dodatkowo symbol „->” wskazuje, że jest to plik dowiązanie symboliczne, które można traktować jak skrót do innego pliku. W tym przypadku wskazuje na kopię programu less w /bin.
Sprawdźmy teraz wersję less w /bin:
ls -lh /bin/less
Ten wpis to oczywiście „prawdziwy” plik binarny. Pierwszy znak to myślnik (-), co oznacza, że jest to zwykły plik, a jego rozmiar wynosi 167 KB. W ten sposób na komputerze znajduje się tylko jedna kopia programu less, ale istnieje dowiązanie symboliczne do niej w innym katalogu, które Bash również uwzględnia podczas przeszukiwania ścieżki.
Sprawdzanie wielu poleceń jednocześnie
Możesz również przekazać wiele programów do polecenia which, a to sprawdzi je w podanej kolejności.
Dla przykładu, jeśli wpiszesz:
which ping cat uptime date head
Wynik będzie zawierał informacje o lokalizacjach wszystkich podanych programów.
Który który jest który?
Możesz również użyć polecenia which w odniesieniu do samego siebie, wpisując:
which which
To może być interesujące, gdy chcesz sprawdzić, czy polecenie uruchamiane przez Bash to to, którego naprawdę chcesz używać.