Muszę znaleźć ścieżkę do danego programu PATH
za pomocą skryptu powłoki. Ścieżka musi być faktyczną pełną ścieżką programu, którą można później przekazać do jednej z exec*
funkcji, która nie przeszukuje PATH
samej, np execv
.
Istnieją takie programy kill
, które są dostępne jako rzeczywisty program i jednocześnie wbudowana powłoka. W takim przypadku potrzebuję pełnej ścieżki do rzeczywistego programu.
Istnieje kilka narzędzi, które mogą znaleźć program w PATH
sposób określony w Sekcji 2.9.1.1, Wyszukiwanie poleceń i wykonywanie standardu POSIX .
Istnieje which
, który nie jest częścią żadnego standardu. Może być zwykłym programem w niektórych systemach, podczas gdy niektóre powłoki zapewniają, że jest wbudowany. Wydaje się, że jest dostępny w większości systemów i powłok, ale powłoki z wbudowaną wersją również zwracają nazwę wbudowanej zamiast ścieżki do pliku wykonywalnego. Ponadto nie jest w żaden sposób ustandaryzowany i może zwracać dane wyjściowe i przyjmować różne opcje.
bash# which kill
/usr/bin/kill
dash# which kill
/usr/bin/kill
fish# which kill
/usr/bin/kill
mksh# which kill
/usr/bin/kill
tcsh# which kill
kill: shell built-in command.
zsh# which kill
kill: shell built-in command
Jest whence
, który jest wbudowany w kilka powłok. Ale niedostępne w wielu powłokach. Zwróci również nazwę wbudowanego zamiast ścieżki do programu. A -p
może zostać przekazane skąd zmienić to zachowanie.
bash# whence kill
bash: whence: command not found
dash# whence kill
dash: 1: whence: not found
fish# whence kill
fish: Unknown command 'whence'
mksh# whence kill
kill
mksh# whence -p kill
/usr/bin/kill
tcsh# whence kill
whence: Command not found.
zsh# whence kill
kill
zsh# whence -p kill
/usr/bin/kill
Jest command
wbudowane określone przez POSIX: 2008 . Niestety wyszukuje również zwykłe polecenia i wbudowane funkcje i zwraca nazwę wbudowanego zamiast ścieżki do programu, ukrytą za wbudowanym o tej samej nazwie. Niektóre stare powłoki jeszcze tego nie zaimplementowały.
bash# command -v kill
kill
dash# command -v kill
kill
fish# command -v kill
/usr/bin/kill
mksh# command -v kill
kill
tcsh# command -v kill
command: Command not found.
zsh# command -v kill
kill
enable
jest to określone w POSIX, czy nie, ale jeśli tak, możesz użyćenable -n which
do wyłączenia wbudowanej powłokiwhich
.realpath
enable
udzielają tylkobash
izsh
type -p
. Zarówno bash, jak i dash pozwalają wypowiedziećcommand
polecenie uruchomienia rzeczywistego pliku wykonywalnego, nawet jeśli istnieje funkcja lub wbudowana funkcja o tej samej nazwie.command
pomija funkcje (i aliasy), ale NIE jest wbudowane, jak poprawnie mówi Q. I nie zawsze możesz użyć shebang, ponieważ nie ma ścieżki, która by dała jakąkolwiek powłokę, a nawet powłokę POSIX, we wszystkich systemach.Odpowiedzi:
Poszukaj go sam.
Testowany w
bash
,dash
,ksh
,mksh
,zsh
Aktualizacja
Powyższe jest dobre dla samodzielnego skryptu, jednak jeśli planujesz osadzić go w większym skrypcie, możesz użyć czegoś podobnego do następującego.
Jest to
IFS
przywracane po znalezieniu dopasowania, również zamieniane naexit
„sreturn
”źródło
IFS
zmienną? Czy nie wystarczy mieć ten zestaw w lokalnej powłoce? Mówiąc o lokalnym, byłbylocal IFS
przenośny? Powyższe może źle oddziaływać, jeśli coś innego oszczędza IFS w ten sam sposób. Patrząc na to pytanie w SE ,local
może działać dla większości powłok, mimo że nie jest POSIX. Umieszczenie oryginalnej wersji w(…)
podpowłoce również może działać.