Mam skrypt bash, który wygląda mniej więcej tak:
#!/bin/bash
if [ $1 = "--test" ] || [ $1 = "-t" ]; then
echo "Testing..."
testing="y"
else
testing="n"
echo "Not testing."
fi
Więc chcę, aby móc nie tylko uruchamiać go z ./script --test
lub ./script -t
, ale także bez argumentów (tylko ./script
), ale najwyraźniej, jeśli zrobię to z bieżącym kodem, wynikiem będzie:
./script: line 3: [: =: unary operator expected
./script: line 3: [: =: unary operator expected
Not testing.
Jak więc go zaprogramować, aby uruchomienie go bez żadnych argumentów wystarczyło, aby else
nie zgłosić błędu? Co ja robię źle?
command-line
bash
scripts
Peter Cordes
źródło
źródło
Odpowiedzi:
„Właściwy sposób” używania długich opcji w skryptach powłoki to narzędzie getopt GNU . Istnieją również getopts, które są wbudowane w bash , ale pozwalają tylko na krótkie opcje, takie jak
-t
. Kilka przykładówgetopt
użycia można znaleźć tutaj .Oto skrypt, który pokazuje, jak podejdę do twojego pytania. Wyjaśnienie większości kroków jest dodawane jako komentarze w samym skrypcie.
Z kilkoma uproszczeniami i usuniętymi komentarzami można to skrócić:
źródło
Kilka sposobów; dwa najbardziej oczywiste to:
$1
w cudzysłowach:if [ "$1" = "--test" ]
Jeszcze lepiej, użyj getopts.
źródło
[ "x$1" = "x--test" ]
ponowne bronienie argumentów wiersza poleceń, które są poprawnymi operatorami dla[
polecenia. (Jest to kolejny powód, dla którego[[ ]]
preferowane jest: to część składni powłoki, a nie tylko wbudowane polecenie).Musisz podać swoje zmienne wewnątrz warunku if. Zastąpić:
z:
Wtedy to zadziała:
Zawsze zawsze podwój swoje cytaty!
źródło
foo=bar echo '$foo'
wydruków$foo
ze zmienną ekspansją , ale zamiast tegofoo=bar echo "$foo"
drukujebar
.Używasz bash. Bash ma świetną alternatywę dla
[
:[[
. Dzięki[[
nie musisz martwić się o wycenę i otrzymujesz znacznie więcej operatorów niż[
, w tym odpowiednie wsparcie dla||
:Lub możesz użyć wyrażeń regularnych:
Oczywiście należy zawsze wykonywać prawidłowe cytowanie, ale nie ma powodu, aby się go trzymać
[
podczas korzystania z bash.źródło
Aby sprawdzić, czy istnieją argumenty (ogólnie i odpowiednio wykonać odpowiednie czynności) Powinno to działać:
źródło
[ -z "$1" ]
?$check
raz, przed jakimkolwiekshift
s, więc lepiej byłoby użyć$1
zamiast tego.#!
podczas dostarczania próbek (powinieneś opisać powłokę poza kodem).