Programuję skrypt powłoki Linuksa , który wydrukuje banery stanu podczas jego wykonywania tylko wtedy, gdy zainstalowanefiglet
jest odpowiednie narzędzie (powiedzmy : osiągalne na ścieżce systemowej) ).
Przykład:
#!/usr/bin/env bash
echo "foo"
figlet "Starting"
echo "moo"
figlet "Working"
echo "foo moo"
figlet "Finished"
Chciałbym, aby mój skrypt działał bez błędów, nawet jeśli niefiglet
jest zainstalowany .
Co może być praktyczną metodą ?
shell
scripting
executable
Sopalajo de Arrierez
źródło
źródło
figlet ... || true
.figlet || true
, ale w twoim przypadku prawdopodobnie jest to funkcja powłoki, którą w postaci zwykłego tekstu Echos Jeśli nie można wydrukować banera, jest bardziej prawdopodobne, że chcesz.Odpowiedzi:
Moja interpretacja użyłaby funkcji otoki nazwanej tak samo jak narzędzie; w tej funkcji uruchom prawdziwe narzędzie, jeśli istnieje:
Wtedy możesz mieć
figlet arg1 arg2...
niezmieniony w swoim skrypcie.@Olorin zaproponował prostszą metodę: zdefiniuj funkcję otoki tylko wtedy, gdy jest to konieczne (jeśli narzędzie nie istnieje):
Jeśli chcesz, aby argumenty
figlet
były drukowane, nawet jeśli figlet nie jest zainstalowany, dostosuj sugestię Olorin w następujący sposób:źródło
command
pochodzi? Nie mam go w moich instalacjach (Red Hat 6.8 Enterprise i Cygwin64).command
jest wbudowaną powłoką POSIX Bourne. Zwykle wykonuje podaną komendę, ale-v
flaga sprawia, że zachowuje się bardziej jaktype
kolejna wbudowana powłoka.type -a command
pokaże ci.which
pokaże tylko pliki wykonywalne na Twoich$PATH
, nie wbudowanych, słowach kluczowych, funkcjach lub aliasach.which
ma znaleźć stosowną alias, bo aliasywhich
się uruchomić/usr/bin/which
(!), a rura jest lista aliasów skorupa jest spojrzeć w (oczywiście\which
hamuje alias i używa tylko programu, który nie wyświetla aliasów.)Możesz sprawdzić, czy
figlet
istniejeźródło
Częstym sposobem na to jest
test -x
aka[ -x
. Oto przykład wzięty z/etc/init.d/ntp
systemu Linux:Ten wariant polega na znajomości pełnej ścieżki pliku wykonywalnego. W
/bin/lesspipe
znalazłem przykład, który działa w ten sposób, łącząc-x
iwhich
polecenie:W ten sposób zadziała to bez uprzedniego wiedzieć, gdzie znajduje
PATH
siębunzip
plik wykonywalny.źródło
which
. I nawet jeśliwhich
zadziałało, użycietest -x
na jego wyjściu jest głupie: jeśli uzyskasz ścieżkęwhich
, istnieje.test -x
nie tylko sprawdza, czy plik istnieje (po totest -e
jest). Sprawdza również, czy plik ma ustawione uprawnienia do wykonywania.which
.Na początku skryptu sprawdź, czy
figlet
istnieje, a jeśli nie, zdefiniuj funkcję powłoki, która nic nie robi:type
sprawdza, czyfiglet
istnieje jako wbudowana powłoka, funkcja, alias lub słowo kluczowe,>/dev/null 2>&1
odrzuca stdin i stdout, aby nie uzyskać żadnych danych wyjściowych, a jeśli nie istnieje,figlet() { :; }
określafiglet
jako funkcję, która nic nie robi.W ten sposób nie musisz edytować każdej linii używanego skryptu
figlet
ani sprawdzać, czy istnieje za każdym razemfiglet
wywołaniu.Możesz dodać komunikat diagnostyczny, jeśli chcesz:
Jako bonus, ponieważ nie wspomniałeś, której powłoki używasz, uważam, że jest ona zgodna z POSIX, więc powinna działać na większości powłok.
źródło
type figlet >/dev/null 2>&1
zehash figlet 2>/dev/null
jeśli używasz bash. (OP powiedział „jeśli jest w mojej ŚCIEŻCE”).Inna alternatywa - wzorzec, który widziałem w skryptach automatycznej konfiguracji projektu:
W twoim konkretnym przypadku możesz nawet zrobić,
Jeśli nie znasz konkretnej ścieżki, możesz wypróbować wiele
elif
(patrz wyżej), aby wypróbować znane lokalizacje, lub po prostu użyć polecenia,PATH
aby zawsze rozwiązać polecenie:Ogólnie, pisząc skrypty, wolę wywoływać polecenia tylko w określonych przeze mnie lokalizacjach. Nie podoba mi się niepewność / ryzyko związane z tym, co użytkownik końcowy mógł w to włożyć
PATH
, być może sam~/bin
.Jeśli na przykład piszę skomplikowany skrypt dla innych, który może usuwać pliki na podstawie danych wyjściowych określonego polecenia, które wywołuję, nie chciałbym przypadkowo odebrać czegoś,
~/bin
co mogłoby lub nie być poleceniem Oczekiwałem.źródło
figlet
był w/usr/local/bin
lub/home/bob/stuff/programs/executable/figlet
?Polecenie bash
type
znajduje polecenie, funkcję, alias, słowo kluczowe lub wbudowane (patrzhelp type
) i drukuje lokalizację lub definicję. Zwraca również kod powrotu reprezentujący wynik wyszukiwania; true (0) jeśli znaleziono. Więc staramy się znaleźćfiglet
na ścieżce (-p
oznacza to tylko wyszukiwanie plików, a nie wbudowane funkcje i funkcje, a także tłumienie komunikatów o błędach), odrzucanie danych wyjściowych (to jest to, co> /dev/null
działa) i jeśli zwraca wartość true (&&
) , wykona sięfiglet
.Jest to prostsze, jeśli
figlet
znajduje się w stałej lokalizacji:Tutaj używamy
test
polecenia (aka[
), aby sprawdzić, czy/usr/bin/figlet
jest wykonywalny (-x
), a jeśli tak (&&
), wykonaj go. Myślę, że to rozwiązanie jest bardziej przenośne niż używanietype
Wydaje mi się, że co uważam za bashizm.Możesz stworzyć funkcję, która zrobi to za Ciebie:
(Cytaty są konieczne ze względu na potencjalne spacje)
Następnie wystarczy zrobić:
źródło
o /, powiedziałbym coś takiego
źródło
Możesz wykonać test, pomijając wszelkie dane wyjściowe i przetestować kod sukcesu / niepowodzenia. Wybierz argumenty, aby ten test był niedrogi. -? lub --help lub --version to oczywiste możliwości.
Dodano w odpowiedzi na komentarz poniżej: jeśli naprawdę chcesz przetestować, że figlet istnieje, a nie to, że jest użyteczny, to zrobiłbyś to
źródło
$?
wynosi 127 (w moim systemie Linux). 127 to „polecenie nie znaleziono”. Ale myślę, że w przypadku racjonalnych poleceń, jeśli sięcommand --help
nie powiedzie, instalacja jest na tyle wykręcona, że równie dobrze może jej nie być!--help
dostępności. Po pierwsze, narzędzia Posix go nie mają, a wytyczne Posix faktycznie go nie zalecają .at --help
kończy się niepowodzeniemat: invalid option -- '-'
, na przykład, i stanem wyjścia130
w moim systemie.-?
--help
--version
... lub możesz dowiedzieć się,figlet -0 --illegal
z których wyjść, i potraktować to jako wskaźnik sukcesu (o ile nie jest to 127, do którego zaliczę klasę jako sabotaż).