LINUX.ORG.RU

Как считать аргументы в баше?

 ,


0

2

Идея такая.

bash script.sh --first something1 --second something2 --n somethingN ...

something1,2,N я хочу записывать в переменную например. Перепробовал несколько конструкций с getopts и просто с while, ничего толкового не вышло. Есть какие-то рабочие конструкции? Типа такой конструкция не работает:

while getopts ":first:second:n:" OPTIONS
do
    case $OPTIONS in
        first ) FIRST=$OPTARG
                echo $FIRST ;;
        ...
        *)      exit 1 ;;
    esac
done

★★★★★

  while true; do
    case "$1" in
      "-f"|"--first") local first="$2"; shift;;
      "--first="*) local first="${1#*=}";;
      "-s"|"--second") local second="$2"; shift;;
      "--second="*) local second="${1#*=}";;
      '--') shift; break;;
      '-'?*) printf '%s\n' "$1" >&2;;
      *) break;;
    esac
    shift
  done
Spoofing ★★★★★
()
Ответ на: комментарий от Spoofing

уже потом. не в цикле. потом. выполняется проверка всех необходимых переменных [ -z "$first" ] || [ -z "$second" ]. будьте последовательны! цикл только перебирает параметры и записывает их. проверки потом.

Spoofing ★★★★★
()
Ответ на: комментарий от Spoofing

А поизящнее нет конструкций? что-то она как-то для двух параметров очень массивно выглядит.

Amet13 ★★★★★
() автор топика
Ответ на: комментарий от Amet13

нет, нету, это нормальная конструкция. по порядку

первый случай: -f и --first принимают аргументом параметр «»

второй случай, когда --first= это один аргумент

аналогично с -s и --second и --second=

затем общепринятая практика, когда надо передать строку, а не аргумент, "--", это UNIX-way.

затем, когда вы передаёете неизвестный "-параметр", выдаёт ошибку в stderr

в конце, когда уже идёт какое-то простое слово, значит параметры кончились и цикл прерывается.

просто вынесите это говнецо в отдельную библиотеку, чтобы глаза не мазолила. а иначе никак нельзя, угу.

Spoofing ★★★★★
()
Ответ на: комментарий от Amet13

Вот такая конструкция работает:

while getopts ":w:c:" options
do
    case $options in
        w ) warning=$OPTARG ;;
        c ) critical=$OPTARG ;;
        * ) echo $usage
            exit $e_unknown ;;
    esac
done

Но тут скрипт нужно запускать с ключами:

bash script.sh -c 1 -w 2
А мне нужно, чтобы вместо c/w можно было использовать слова, и с двойным дефисом например:
bash script.sh --crit 1 --warn 2

Amet13 ★★★★★
() автор топика
Ответ на: комментарий от Amet13

getopts в bash этого не умеет, ради --полновесных-аргументов вам нужен именно тот костыль, который дал вам я.

Spoofing ★★★★★
()
Ответ на: комментарий от Spoofing

Хорошо, спасибо, оставлю этот вариант на крайняк, если ничего проще нет.

Amet13 ★★★★★
() автор топика
Ответ на: комментарий от Spoofing

В баше кавычки не нужны.

case $1 in
    -f|--first)
    --first=*)
    -s|--second)
    --second=*)
    --)
    -?*)
    *)

lexazloy
()

Тебе нужен getopt, а не getopts

getopt умеет длинные параметры

anonymous
()

$ cat /usr/share/doc/util-linux/examples/getopt-parse.bash

#!/bin/bash

# A small example program for using the new getopt(1) program.
# This program will only work with bash(1)
# An similar program using the tcsh(1) script language can be found
# as parse.tcsh

# Example input and output (from the bash prompt):
# ./parse.bash -a par1 'another arg' --c-long 'wow!*\?' -cmore -b " very long "
# Option a
# Option c, no argument
# Option c, argument `more'
# Option b, argument ` very long '
# Remaining arguments:
# --> `par1'
# --> `another arg'
# --> `wow!*\?'

# Note that we use `"$@"' to let each command-line parameter expand to a
# separate word. The quotes around `$@' are essential!
# We need TEMP as the `eval set --' would nuke the return value of getopt.
TEMP=`getopt -o ab:c:: --long a-long,b-long:,c-long:: \
     -n 'example.bash' -- "$@"`

if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi

# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"

while true ; do
	case "$1" in
		-a|--a-long) echo "Option a" ; shift ;;
		-b|--b-long) echo "Option b, argument \`$2'" ; shift 2 ;;
		-c|--c-long)
			# c has an optional argument. As we are in quoted mode,
			# an empty parameter will be generated if its optional
			# argument is not found.
			case "$2" in
				"") echo "Option c, no argument"; shift 2 ;;
				*)  echo "Option c, argument \`$2'" ; shift 2 ;;
			esac ;;
		--) shift ; break ;;
		*) echo "Internal error!" ; exit 1 ;;
	esac
done
echo "Remaining arguments:"
for arg do echo '--> '"\`$arg'" ; done
anonymous
()
Ответ на: комментарий от anonymous

Видел я это, то ли я не до конца понял, то ли действительно нельзя выдрать в переменную, то что после -a:

bash test -a 123 -b 456
Option a
Option b, argument `456'
Remaining arguments:
--> `123'
Нужно 123 засунуть куда-нибудь.

Amet13 ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.