сценарій bash: якщо аргументи дорівнюють цій рядку, визначте змінну, подібну цій рядку


225

Я роблю якийсь сценарій bash, і тепер я отримав один виклик змінної sourceта один масив, що викликається samples, як це:

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

оскільки я хочу розширити кількість джерел (і в кожного джерела є свої зразки), я намагався додати деякі аргументи для цього. Я спробував це:

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

але коли я запустив свій сценарій, source countries.sh countryце не спрацювало. Що я роблю неправильно?


2
як це не працює? Коли ви запускаєте його, ви отримуєте помилку, або він говорить "спробуйте ще раз", або щось інше?
зло Отто

2
так, ви можете подумати, «питання дуже просте». але ви про це думали деякий час. Подумайте, як редагувати своє запитання, щоб включити необхідні висновки та будь-які повідомлення про помилки, які ви отримуєте. +1 за те, що насправді щось намагається та добре форматує запитання. Щасти.
обстріл

Чому цей код збігається із запропонованим та прийнятим рішенням? Це заплутано ... Я здогадуюсь, що в початковому запитанні не було пробілів одразу після вступної дужки та перед заключною дужкою речення if?
Стеф

6
@Stef якщо уважно придивитися, $1="country"vs.$1 = "country"
Буде

Відповіді:


413

Не забувайте про місця:

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

121
Я не можу повірити, що я витрачаю на це три години, і це була лише проблема простору !!!! ... БЛАГОДАРИ @Alex
Алехандро

1
Для чого ви використовуєте samples="US Canada Mexico..."після введення створення масиву раніше samples=(US Canada Mexico...)?
користувач невідомий

10
У мене виникли проблеми з цим, коли змінна зліва була порожньою рядком. Виправлення було if [ "$1" = "country" ]; then.
andrewb

8
Гаразд, це все. Bash офіційно отримує мій голос за те, що я маю на увазі саму застарілу досі використану командну мову. Синтаксис просто такий не інтуїтивний, що болить. Дійсно немає місця для нього у 2016+. Автори @Systemd: чи можете ви зробити "наступним проектом" створення "оболонки Linux", яка не смокче "? Я кину на тебе гроші.
масі

3
@masi іноді я думаю, що початковий намір Unix був "безпека роботи через незрозумілість". якби інструменти були виразними у використанні, важкими для розуміння, і взагалі поза досяжності великих немитих без внутрішніх знань, переданих від майстра до падуана, це гарантувало б, що для тих, хто «знає», завжди знайдеться робота. ця філософія очевидна у всій конструкції "RFC" та квітковій мові, що використовується в людських документах, які технічно розповідають, як користуватися інструментами, насправді просто були там, щоб виконати вимогу задокументувати інструменти. мало що змінилося.
несинхронізований

184

Для порівняння рядків у bash можна використовувати оператори "=" або "==". Важливим фактором є відстань всередині дужок. Правильний метод полягає в тому, щоб дужки містили пробіли всередині, а оператори містили пробіли навколо. В деяких випадках працюють різні комбінації; однак наступне покликане стати універсальним прикладом.

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

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

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

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

Крім того, зверніть увагу, що подвійні дужки обробляються дещо інакше порівняно з одинарними дужками ...

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).

Я сподіваюся, що це допомагає!


12

Здається, ви шукаєте для аналізу аргументів командного рядка у вашому скрипті bash. Я нещодавно сам це шукав. Я натрапив на наступне, що, на мою думку, допоможе вам у розборі аргументів:

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

Я додав фрагмент нижче як 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 тест -r сервер -p пароль -v

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.