Приложение останавливается, прежде чем что-либо показывать

Другое решение без getopt [s], POSIX, старый стиль Unix

Как и в , решение Bruno Bronosky опубликовано , здесь это одно без использования getopt(s).

Основная отличительная особенность моего решения заключается в том, что он позволяет объединять параметры, как tar -xzf foo.tar.gz, равно tar -x -z -f foo.tar.gz. И так же, как в tar, ps и т. Д. Ведущий дефис является необязательным для блока коротких опций (но это можно легко изменить).

Код с примерами опций

#!/bin/sh

echo
echo "POSIX-compliant getopt(s)-free old-style-supporting option parser from phk@[se.unix]"
echo

print_usage() {
  echo "Usage:

  $0 {a|b|c} [ARG...]

Options:

  --aaa-0-args
  -a
    Option without arguments.

  --bbb-1-args ARG
  -b ARG
    Option with one argument.

  --ccc-2-args ARG1 ARG2
  -c ARG1 ARG2
    Option with two arguments.

" >&2
}

if [ $# -le 0 ]; then
  print_usage
  exit 1
fi

opt=
while :; do

  if [ $# -le 0 ]; then

    # no parameters remaining -> end option parsing
    break

  elif [ ! "$opt" ]; then

    # we are at the beginning of a fresh block
    # remove optional leading hyphen and strip trailing whitespaces
    opt=$(echo "$1" | sed 's/^-\?\([a-zA-Z0-9\?-]*\)/\1/')

  fi

  # get the first character -> check whether long option
  first_chr=$(echo "$opt" | awk '{print substr($1, 1, 1)}')
  [ "$first_chr" = - ] && long_option=T || long_option=F

  # note to write the options here with a leading hyphen less
  # also do not forget to end short options with a star
  case $opt in

    -)

      # end of options
      shift
      break
      ;;

    a*|-aaa-0-args)

      echo "Option AAA activated!"
      ;;

    b*|-bbb-1-args)

      if [ "$2" ]; then
        echo "Option BBB with argument '$2' activated!"
        shift
      else
        echo "BBB parameters incomplete!" >&2
        print_usage
        exit 1
      fi
      ;;

    c*|-ccc-2-args)

      if [ "$2" ] && [ "$3" ]; then
        echo "Option CCC with arguments '$2' and '$3' activated!"
        shift 2
      else
        echo "CCC parameters incomplete!" >&2
        print_usage
        exit 1
      fi
      ;;

    h*|\?*|-help)

      print_usage
      exit 0
      ;;

    *)

      if [ "$long_option" = T ]; then
        opt=$(echo "$opt" | awk '{print substr($1, 2)}')
      else
        opt=$first_chr
      fi
      printf 'Error: Unknown option: "%s"\n' "$opt" >&2
      print_usage
      exit 1
      ;;

  esac

  if [ "$long_option" = T ]; then

    # if we had a long option then we are going to get a new block next
    shift
    opt=

  else

    # if we had a short option then just move to the next character
    opt=$(echo "$opt" | awk '{print substr($1, 2)}')

    # if block is now empty then shift to the next one
    [ "$opt" ] || shift

  fi

done

echo "Doing something..."

exit 0

Для примера использования см. Раздел «Дополнительные параметры». примеры ниже.

Позиция опций с аргументами

Для чего его ценность там опционы с аргументами не являются последними (должны быть только длинные варианты). Таким образом, пока, например, в tar (по крайней мере, в некоторых реализациях) параметры f должны быть последними, потому что имя файла следует (tar xzf bar.tar.gz работает, но tar xfz bar.tar.gz не делает) это не так (см. более поздние примеры).

Несколько опций с аргументами

В качестве еще одного бонуса параметры параметра потребляются в порядке параметров по параметрам с требуемыми параметрами. Просто посмотрите на вывод моего скрипта здесь с помощью командной строки abc X Y Z (или -abc X Y Z):

Option AAA activated!
Option BBB with argument 'X' activated!
Option CCC with arguments 'Y' and 'Z' activated!

Длинные опции также объединены

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

  • -cba Z Y X
  • cba Z Y X
  • -cb-aaa-0-args Z Y X
  • -c-bbb-1-args Z Y X -a
  • --ccc-2-args Z Y -ba X
  • c Z Y b X a
  • -c Z Y -b X -a
  • --ccc-2-args Z Y --bbb-1-args X --aaa-0-args

Все это приводит к:

Option CCC with arguments 'Z' and 'Y' activated!
Option BBB with argument 'X' activated!
Option AAA activated!
Doing something...

Не в этом решении

Дополнительные аргументы

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

Все становится еще сложнее с несколькими возможными параметрами. Я бы посоветовал не делать параметры, пытаясь быть умными, определяя, может ли для него аргумент или нет (например, с опцией просто принимает число как необязательный аргумент), потому что это может сломаться в будущем.

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

Опционные аргументы, введенные с знаком равенства

Как и с необязательными аргументами, я не поклонник этого (BTW, есть ли там нить для обсуждения плюсов и минусов разных стилей параметров?), но если вы этого хотите, вы могли бы реализовать его сами, как это сделано в http://mywiki.wooledge.org/BashFAQ/035#Manual_loop с оператором case --long-with-arg=?*, а затем снятие знака равенства (это BTW сайт, в котором говорится, что создание конкатенации параметров возможно с некоторыми усилиями, но «оставило [это] как упражнение для читателя», что заставило меня взять их на их слово, но я начал с нуля).

Другие примечания

POSIX-совместимый, работает даже на ancie nt Настройка Busybox, с которой мне приходилось иметь дело (например, cut, head и getopts отсутствуют.

1
задан Gustavo Brandão 26 March 2019 в 18:15
поделиться

2 ответа

Я нашел, где происходит ошибка, слава Богу! После долгого дня анализа кода я обнаружил свою ошибку, которая связана с запросом на разрешение и работает следующим образом:

- Начиная с Android 6.0, приложения должны запрашивать разрешение на использование некоторых функций из устройство (я сделал эту структуру). Но происходит то, что ниже 6.0 не нужно запрашивать разрешение, и тогда у меня возник конфликт.

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

0
ответ дан Gustavo Brandão 26 March 2019 в 18:15
поделиться

Похоже, что вы делаете что-то в собственном коде своего приложения, которое не поддерживается в Android 5. Из комментариев вы можете воспроизвести это в эмуляторе. Так что следующий шаг, чтобы выяснить, что ломает, - это посмотреть на ваш нативный код или даже использовать отладку нативного кода в эмуляторе, чтобы выяснить, в чем его ошибка.

Здесь приведены некоторые документы по отладке собственного кода в Androud Studio .

0
ответ дан Nick Fortescue 26 March 2019 в 18:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: