Z C, jaki jest najłatwiejszy sposób uruchomienia standardowego narzędzia (np. Ps), a żadnego innego?
Czy POSIX gwarantuje na przykład, że standard ps
jest włączony, /bin/ps
czy powinienem zresetować zmienną środowiskową PATH do tego, co otrzymuję, confstr(_CS_PATH, pathbuf, n);
a następnie uruchomić narzędzie poprzez wyszukiwanie PATH?
/bin
, tj./bin/ed
Muszą być użyteczne jeśli ed jest zainstalowany. Nie mogę go teraz znaleźć, ale wiem, że LSB zależy od tego, i skutecznie broniłem raportów o błędach, używając tego jako uzasadnienia, więc przynajmniej w pewnym momencie musiało to być prawdą. (Lub było to coś innego niż POSuX i źle pamiętam, ale reszta jest prawdą.)Odpowiedzi:
Nie, nie robi tego, głównie dlatego, że nie wymaga domyślnej zgodności systemów ani zgodności tylko ze standardem POSIX (z wyłączeniem jakiegokolwiek innego standardu).
Na przykład Solaris (system z certyfikatem zgodności) wybrał wsteczną kompatybilność swoich narzędzi
/bin
, co wyjaśnia, dlaczego zachowują się one w tajemniczy sposób, i zapewnia narzędzia zgodne z POSIX w oddzielnych lokalizacjach (/usr/xpg4/bin
,/usr/xpg6/bin
... dla różnych wersji XPG (teraz scalonych) do standardu POSIX), które faktycznie są częścią opcjonalnych komponentów Solaris).Nawet
sh
nie ma gwarancji, że wejdzie/bin
. W Solarisie/bin/sh
była to powłoka Bourne'a (więc nie jest zgodna z POSIX) aż do Solaris 10, podczas gdy teraz jest to ksh93 w Solaris 11 (wciąż nie w pełni zgodna z POSIX, ale w praktyce bardziej niż/usr/xpg4/bin/sh
).W C możesz
exec*p()
założyć i założyć, że jesteś w środowisku POSIX (w szczególności w odniesieniu doPATH
zmiennej środowiskowej).Możesz także ustawić
PATH
zmienną środowiskowąLub możesz określić w czasie kompilacji ścieżkę narzędzi POSIX, które chcesz uruchomić (pamiętając, że w niektórych systemach, takich jak GNU, potrzebujesz więcej kroków, takich jak ustawienie
POSIXLY_CORRECT
zmiennej w celu zapewnienia zgodności).Możesz także spróbować takich rzeczy jak:
W nadziei, że to
sh
się$PATH
, że jest podobny do Bourne, że istnieje równieżgetconf
i to, że jest to jedna z wersji POSIX jesteś zainteresowany.źródło
/usr/bin/env
istnieje i jest w większości zgodny z POSIX./usr/bin/env
To jeszcze mniej przenośny (w praktyce) hack niż/bin/sh
. Za POSIX, przenośny sposób napisać skrypt jest z nie#!
w ogóle . Jeśli plik jest wykonywalny, aleENOEXEC
(nie jest to poprawny plik binarny),execvp
należy go wykonać za pomocą standardowej powłoki. :-) Oczywiście w praktyce jest to zły pomysł i powinieneś go po prostu użyć#!/bin/sh
.$PATH
z powłoki zamiast z C.Właściwie w większości odpowiedziałbym tak . POSIX gwarantuje:
Chociaż nie jest koniecznie zagwarantowane, że każde narzędzie powinno znajdować się w określonym katalogu we wszystkich systemach (
/bin/ps
), to zawsze gwarantowane , aby móc znaleźć można w domyślnym PATH systemu, jako plik wykonywalny.Rzeczywiście, jedynym sposobem określonym w standardzie, aby to zrobić w standardzie jest (w C) za pomocą
unistd.h
_CS_PATH lub w powłoce, za pomocą kombinacjicommand
igetconf
narzędzi, tj.PATH="$(command -p getconf PATH)" command -v ps
Zawsze musi zwracać unikalną bezwzględną ścieżkę zgodną z POSIXps
dostarczane w określonym systemie. Oznacza to, że o ile ścieżki są zdefiniowane w implementacji, które ścieżki są zawarte w domyślnej zmiennej systemowej PATH, są one wykorzystywane muszą być zawsze dostępne, unikalne i zgodne, w jednej ze ścieżek tam określonych.Patrz: < unistd.h >, polecenie .
źródło
PATH=$(command -p getconf PATH)
to tylko z powłoki POSIX w środowisku POSIX. POSIX nie określa, w jaki sposób wchodzisz do tego środowiska, wystarczy, że zostanie to udokumentowane. Na przykład w systemie Solaris masz a/usr/xpg4/bin/getconf
i a,/usr/xpg6/bin/getconf
które zwracałyby różne wartości dla_CS_PATH
dwóch różnych wersji standardu, i żadna z nich/usr/xpg4/bin
nie/usr/xpg6/bin
ma wartości domyślnej$PATH
. Jest taki,/usr/bin/getconf
który IIRC zapewnia zgodność z XPG4.sh
z POSIX z dowolnej domyślnej powłoki .getconf
w domyślnym$PATH
systemie powinien znajdować się rozkaz . Na przykład uzyskanie środowiska POSIX może wymagać uruchomienia warstwy emulacji, bez której w ogóle nie uruchomiłbyś żadnego polecenia podobnego do Uniksa (na przykład Windows). Gdy jesteś w środowisku zgodnym,getconf PATH
będzie Ci$PATH
się dostać do mediów zgodnych, ale jeśli były w środowisku POSIX, który był już prawdopodobnie w tym przypadku. Pamiętaj, żegetconf ps
może wrócićps
. Mając naps
polecenie wbudowane jest dozwolone.