Skrypty bash: jeśli argumenty są równe temu ciągowi, zdefiniuj zmienną taką jak ten ciąg


225

Robię skrypt bash, a teraz mam jedno wywołanie zmiennej sourcei jedną tablicę samples, tak jak poniżej:

source='country'
samples=(US Canada Mexico...)

ponieważ chcę zwiększyć liczbę źródeł (a każde źródło ma swoje własne próbki), próbowałem dodać kilka argumentów, aby to zrobić. Próbowałem tego:

source=""
samples=("")
if [ $1="country" ]; then
   source="country"
   samples="US Canada Mexico..."
else
   echo "try again"
fi

ale kiedy uruchomiłem skrypt source countries.sh country, nie działało. Co ja robię źle?


2
jak to nie działa Po uruchomieniu pojawia się błąd lub komunikat „spróbuj ponownie” lub coś innego?
evil otto

2
tak, możesz pomyśleć „pytanie jest bardzo proste”. ale myślałeś o tym przez jakiś czas. Rozważ edycję pytania, aby uwzględnić wymagane dane wyjściowe i wszelkie otrzymywane komunikaty o błędach. +1 za faktyczne wypróbowanie czegoś i dobre sformatowanie pytania. powodzenia.
łupacz

Dlaczego ten kod jest taki sam jak proponowane i zaakceptowane rozwiązanie? To mylące ... Domyślam się, że początkowe pytanie nie miało spacji zaraz po nawiasie otwierającym i przed nawiasiem zamykającym zdania if?
Stef

6
@Stef, jeśli przyjrzysz się uważnie, $1="country"kontra$1 = "country"
Will

Odpowiedzi:


413

Nie zapomnij o spacjach:

source=""
samples=("")
if [ $1 = "country" ]; then
   source="country"
   samples="US Canada Mexico..."
else
  echo "try again"
fi

121
Nie mogę uwierzyć, że spędziłem na tym trzy godziny, a to był tylko problem ze spacjami !!!! ... DZIĘKI @Alex
Alejandro

1
Dlaczego korzystasz samples="US Canada Mexico..."po wprowadzeniu tworzenia tablicy wcześniej samples=(US Canada Mexico...)?
użytkownik nieznany

10
Wystąpiły problemy z tym, gdy zmienna po lewej stronie była pustym ciągiem. Naprawiono if [ "$1" = "country" ]; then.
andrewb

8
Okej, to tyle. Bash oficjalnie otrzymuje mój głos za to, że jest najbardziej przestarzałym, ale wciąż używanym językiem poleceń. Składnia jest tak intuicyjna, że ​​boli. Naprawdę nie ma na to miejsca w 2016+. @Systemd autorzy: czy możesz zrobić „budowanie powłoki Linuxa, która nie jest do bani”, następnym projektem? Wyrzucę na ciebie pieniądze.
masi

3
@masi czasami myślę, że pierwotną intencją systemu uniksowego było „bezpieczeństwo pracy poprzez zaciemnienie”. gdyby narzędzia były tajemnicze w użyciu, trudne do zrozumienia i generalnie poza zasięgiem wielkiego niemytego bez wewnętrznej wiedzy przekazywanej z mistrza na padwan, zapewniłoby to, że zawsze będzie praca dla tych, którzy „wiedzą”. filozofia ta jest widoczna w całej konstrukcji „RFC” i kwiecistym języku używanym w dokumentach człowieka, który choć technicznie mówi ci, jak korzystać z narzędzi, tak naprawdę po prostu spełnił wymóg udokumentowania narzędzi. niewiele się zmieniło.
niezsynchronizowany

184

Możesz użyć operatora „=” lub „==” do porównania ciągów w bash. Ważnym czynnikiem jest odstęp w nawiasach. Właściwą metodą jest umieszczenie w nawiasach odstępów, a operatorów - umieszczenie odstępów. W niektórych przypadkach działają różne kombinacje; jednak poniższe zamierzenie ma być uniwersalnym przykładem.

if [ "$1" == "something" ]; then     ## GOOD

if [ "$1" = "something" ]; then      ## GOOD

if [ "$1"="something" ]; then        ## BAD (operator spacing)

if ["$1" == "something"]; then       ## BAD (bracket spacing)

Uwaga: podwójne nawiasy klamrowe są obsługiwane nieco inaczej niż pojedyncze nawiasy ...

if [[ $a == z* ]]; then   # True if $a starts with a "z" (pattern matching).
if [[ $a == "z*" ]]; then # True if $a is equal to z* (literal matching).

if [ $a == z* ]; then     # File globbing and word splitting take place.
if [ "$a" == "z*" ]; then # True if $a is equal to z* (literal matching).

Mam nadzieję że to pomogło!


12

Wygląda na to, że chcesz przeanalizować argumenty wiersza polecenia w skrypcie bash. Ostatnio sam tego szukałem. Natknąłem się na następujące, które moim zdaniem pomogą ci w analizie argumentów:

http://rsalveti.wordpress.com/2007/04/03/bash-parsing-arguments-with-getopts/

Dodałem poniższy fragment jako tl; dr

#using : after a switch variable means it requires some input (ie, t: requires something after t to validate while h requires nothing.
while getopts ht:r:p:v OPTION
do
     case $OPTION in
         h)
             usage
             exit 1
             ;;
         t)
             TEST=$OPTARG
             ;;
         r)
             SERVER=$OPTARG
             ;;
         p)
             PASSWD=$OPTARG
             ;;
         v)
             VERBOSE=1
             ;;
         ?)
             usage
             exit
             ;;
     esac
done

if [[ -z $TEST ]] || [[ -z $SERVER ]] || [[ -z $PASSWD ]]
then
     usage
     exit 1
fi

./script.sh -t test -r serwer -p hasło -v

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.