Вопрос:

Bash Shell Script - проверьте наличие флага и получите его значение

linux bash shell debian

96463 просмотра

4 ответа

4147 Репутация автора

Я пытаюсь сделать сценарий оболочки, который предназначен для запуска следующим образом:

script.sh -t application

Во-первых, в моем скрипте я хочу проверить, был ли скрипт запущен с флагом -t. Например, если он был запущен без такого флага, я хочу, чтобы он выдавал ошибку:

script.sh

Во-вторых, предполагая наличие флага -t, я хочу получить значение и сохранить его в переменной, которую я могу использовать в своем скрипте, например, так:

FLAG="application"

Пока что единственный прогресс, который я смог сделать в этом, заключается в том, что $ @ захватывает все аргументы командной строки, но я не знаю, как это связано с флагами, или если это вообще возможно.

Автор: Jimmy Источник Размещён: 21.01.2013 09:19

Ответы (4)


95 плюса

110642 Репутация автора

Решение

Вы должны прочитать этот урок getopts .

Пример с -aключом, который требует аргумента:

#!/bin/bash

while getopts ":a:" opt; do
  case $opt in
    a)
      echo "-a was triggered, Parameter: $OPTARG" >&2
      ;;
    \?)
      echo "Invalid option: -$OPTARG" >&2
      exit 1
      ;;
    :)
      echo "Option -$OPTARG requires an argument." >&2
      exit 1
      ;;
  esac
done

Как сказал Грейбот ( getopt! = getopts):

Внешнюю команду getopt (1) никогда нельзя использовать безопасно, если только вы не знаете, что это GNU getopt, вы вызываете ее специфичным для GNU способом и убедитесь, что GETOPT_COMPATIBLE отсутствует в среде. Вместо этого используйте getopts (встроенную оболочку) или просто переключайтесь между позиционными параметрами.

Автор: Gilles Quenot Размещён: 21.01.2013 09:24

24 плюса

30018 Репутация автора

Используйте $#для получения количества аргументов, если оно не равно 2, недостаточно аргументов:

if [ $# -ne 2 ]; then
   usage;
fi

Затем, проверьте, $1равно ли -t, иначе был использован неизвестный флаг:

if [ "$1" != "-t" ]; then
  usage;
fi

Наконец хранить $2в FLAG:

FLAG=$2

Примечание: usage()это некоторая функция, показывающая синтаксис. Например:

function usage {
   cat << EOF
Usage: script.sh -t <application>

Performs some activity
EOF
   exit 1
}
Автор: Veger Размещён: 21.01.2013 09:24

0 плюса

547 Репутация автора

Попробуйте shFlags - Расширенная библиотека флагов командной строки для сценариев оболочки Unix.

http://code.google.com/p/shflags/

Это очень хорошо и очень гибко.

ТИПЫ ФЛАГОВ: Это список DEFINE _ *, которые вы можете сделать. Все флаги имеют имя, значение по умолчанию, строку справки и необязательное «короткое» имя (однобуквенное имя). Некоторые флаги имеют другие аргументы, которые описаны с флагом.

DEFINE_string: принимает любой ввод и интерпретирует его как строку.

DEFINE_boolean: обычно не принимает никаких аргументов: например, --myflag для установки FLAGS_myflag в значение true или --nomyflag для установки FLAGS_myflag в значение false. Кроме того, вы можете сказать --myflag = true или --myflag = t или --myflag = 0 или --myflag = false или --myflag = f или --myflag = 1. Передача параметра имеет тот же эффект, что и пропуск вариант один раз.

DEFINE_float: принимает входные данные и интерпретирует их как число с плавающей запятой. Так как оболочка не поддерживает плавающие как таковые, входные данные просто проверяются как допустимые значения с плавающей запятой.

DEFINE_integer: принимает входные данные и интерпретирует их как целое число.

СПЕЦИАЛЬНЫЕ ФЛАГИ: Есть несколько флагов, которые имеют особое значение: --help (или -?) Печатает список всех флагов понятным для человека способом --flagfile = foo read flags из foo. (еще не реализовано) - как и в getopt (), прекращает обработку флага

ПРИМЕР ИСПОЛЬЗОВАНИЯ:

-- begin hello.sh --
 ! /bin/sh
. ./shflags
DEFINE_string name 'world' "somebody's name" n
FLAGS "$@" || exit $?
eval set -- "${FLAGS_ARGV}"
echo "Hello, ${FLAGS_name}."
-- end hello.sh --

$ ./hello.sh -n Kate
Hello, Kate.

Примечание: я взял этот текст из документации shflags

Автор: Anandkumar Размещён: 06.11.2017 06:43

6 плюса

61 Репутация автора

Вот обобщенный простой интерфейс аргументов команды, который вы можете вставить в начало всех ваших скриптов.

#!/bin/bash

declare -A flags
declare -A booleans
args=()

while [ "$1" ];
do
    arg=$1
    if [ "${1:0:1}" == "-" ]
    then
      shift
      rev=$(echo "$arg" | rev)
      if [ -z "$1" ] || [ "${1:0:1}" == "-" ] || [ "${rev:0:1}" == ":" ]
      then
        bool=$(echo ${arg:1} | sed s/://g)
        booleans[$bool]=true
        echo \"$bool\" is boolean
      else
        value=$1
        flags[${arg:1}]=$value
        shift
        echo \"$arg\" is flag with value \"$value\"
      fi
    else
      args+=("$arg")
      shift
      echo \"$arg\" is an arg
    fi
done


echo -e "\n"
echo booleans: ${booleans[@]}
echo flags: ${flags[@]}
echo args: ${args[@]}

echo -e "\nBoolean types:\n\tPrecedes Flag(pf): ${booleans[pf]}\n\tFinal Arg(f): ${booleans[f]}\n\tColon Terminated(Ct): ${booleans[Ct]}\n\tNot Mentioned(nm): ${boolean[nm]}"
echo -e "\nFlag: myFlag => ${flags["myFlag"]}"
echo -e "\nArgs: one: ${args[0]}, two: ${args[1]}, three: ${args[2]}"

Запустив команду:

bashScript.sh firstArg -pf -myFlag "my flag value" secondArg -Ct: thirdArg -f

Выход будет таким:

"firstArg" is an arg
"pf" is boolean
"-myFlag" is flag with value "my flag value"
"secondArg" is an arg
"Ct" is boolean
"thirdArg" is an arg
"f" is boolean


booleans: true true true
flags: my flag value
args: firstArg secondArg thirdArg

Boolean types:
    Precedes Flag(pf): true
    Final Arg(f): true
    Colon Terminated(Ct): true
    Not Mentioned(nm): 

Flag: myFlag => my flag value

Args: one => firstArg, two => secondArg, three => thirdArg

В основном, аргументы делятся на логические флаги и общие аргументы. Делая это таким образом, пользователь может устанавливать флаги и логические значения в любом месте, пока он / она сохраняет общие аргументы (если они есть) в указанном порядке.

Позвольте мне и теперь вам больше никогда не иметь дело с разбором аргументов bash!

Вы можете просмотреть обновленный скрипт здесь

Это было чрезвычайно полезно за последний год. Теперь он может имитировать область видимости, добавляя переменные к параметру области видимости.

Просто назовите сценарий как

replace() (
  source $FUTIL_REL_DIR/commandParser.sh -scope ${FUNCNAME[0]} "$@"
  echo ${replaceFlags[f]}
  echo ${replaceBooleans[b]}
)

Не похоже, что я реализовал область действия аргумента, не уверен, почему, я думаю, он мне пока не нужен.

Автор: jozsef morrissey Размещён: 03.09.2018 10:04
Вопросы из категории :
32x32