53

Я пытаюсь написать скрипт, в котором я хочу проверить, соответствует ли какой-либо из параметров, переданных скрипту bash, строке. То, как я сейчас это настроил,

if [ "$3" != "-disCopperBld" -a "$4" != "-disCopperBld" -a "$5" != "-disCopperBld" -a "$6" != "-disCopperBld"]

но может быть большое количество параметров, поэтому мне было интересно, есть ли лучший способ сделать это?

Спасибо

РЕДАКТИРОВАТЬ: я попробовал этот кусок кода, и вызвал сценарий с параметром -disableVenusBld, но он по-прежнему выводит "Начало сборки". Я делаю что-то неправильно? Заранее спасибо!

while [ $# -ne 0 ]
do
    arg="$1"
    case "$arg" in
        -disableVenusBld)
            disableVenusBld=true
            ;;
        -disableCopperBld)
            disableCopperBld=true
            ;;
        -disableTest)
            disableTest=true
            ;;
        -disableUpdate)
            disableUpdate=true
            ;;
        *)
            nothing="true"
            ;;
    esac
    shift
done

if [ "$disableVenusBld" != true ]; then
    echo "Starting build"
fi

4 ответа4

53

Похоже, вы выполняете обработку опций в скрипте оболочки. Вот идиома для этого:

#! /bin/sh -

# idiomatic parameter and option handling in sh
while test $# -gt 0
do
    case "$1" in
        --opt1) echo "option 1"
            ;;
        --opt2) echo "option 2"
            ;;
        --*) echo "bad option $1"
            ;;
        *) echo "argument $1"
            ;;
    esac
    shift
done

exit 0

(Есть несколько соглашений для отступа в ;; , и некоторые оболочки позволяют задавать параметры как (--opt1) , чтобы помочь с сопоставлением фигурных скобок, но это основная идея)

18

Это сработало для меня. Он делает именно то, что вы просили больше ничего (без обработки опций). Хорошо это или плохо - упражнение для плаката :)

if [[ "$@" == "your string" ]]
then
    echo "YES"
else
    echo "NO"
fi

Обратите внимание, что использование $@ вместо $* вместе с тем, что оно заключено в кавычки, гарантирует гибкость в случае тестовой строки с белыми символами. С $* только "your" или "string" . Однако не было бы никакой разницы, если бы не было пробелов.

Смотрите это объяснение о различиях в поведении.

8

Как насчет поиска (с подстановочными знаками) всего пространства параметров:

if [[ $@ == *'-disableVenusBld'* ]]
then

Изменить: Хорошо, хорошо, так что это не был популярный ответ. Как насчет этого, это прекрасно!

if [[ "${@#-disableVenusBld}" = "$@" ]]
then
    echo "Did not find disableVenusBld"
else
    echo "Found disableVenusBld"
fi

Edit2: хорошо, хорошо, может быть, это не идеально ... Думаю, что это работает, только если -param находится в начале списка и также будет соответствовать -paramXZY или -paramABC. Я все еще думаю, что оригинальная проблема может быть решена очень хорошо с манипулированием строк bash, но я не совсем взломал это здесь ... -Можете?

2
disCopperBld=
for x; do
  if [ "$x" = "-disCopperBld" ]; then disCopperBld=1; break; fi
done
if [ -n "$disCopperBld" ]; then
  ...
fi

Если вам нужно протестировать только параметры, начинающиеся с $3 , выполните поиск в функции:

## Usage: search_trailing_parameters NEEDLE NUM "$@"
## Search NEEDLE amongst the parameters, skipping $1 through ${$NUM}.
search_trailing_parameters () {
  needle=$1
  shift $(($2 + 2))
  for x; do
    if [ "$x" = "$needle" ]; then return 0; fi
  done
  return 1
}
if search_trailing_parameters -disCopperBld 2 "$@"; then
  ...
fi

Но мне интересно, почему вы пытаетесь сделать это в первую очередь, это не является общей потребностью. Обычно вы обрабатываете варианты по порядку, как в ответе Денниса на предыдущий вопрос.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .