Nano Hash - криптовалюты, майнинг, программирование

Как я могу добавить метод справки к сценарию оболочки?

Как проверить, передан ли атрибут -h в сценарий оболочки? Я хотел бы отображать справочное сообщение, когда пользователь звонит myscript.sh -h.

29.03.2011


Ответы:


1

вот пример для bash:

usage="$(basename "$0") [-h] [-s n] -- program to calculate the answer to life, the universe and everything

where:
    -h  show this help text
    -s  set the seed value (default: 42)"

seed=42
while getopts ':hs:' option; do
  case "$option" in
    h) echo "$usage"
       exit
       ;;
    s) seed=$OPTARG
       ;;
    :) printf "missing argument for -%s\n" "$OPTARG" >&2
       echo "$usage" >&2
       exit 1
       ;;
   \?) printf "illegal option: -%s\n" "$OPTARG" >&2
       echo "$usage" >&2
       exit 1
       ;;
  esac
done
shift $((OPTIND - 1))

Чтобы использовать это внутри функции:

  • используйте "$FUNCNAME" вместо $(basename "$0")
  • добавьте local OPTIND OPTARG перед вызовом getopts
29.03.2011
  • Я пытаюсь сделать это внутри функции, но когда я пытаюсь запустить функцию, я получаю эту ошибку basename: invalid option - 'b'. Похоже, он пытается передать -bash в basename с начальным тире. 07.08.2013
  • Внутри функции используйте "$FUNCNAME", а не "$0". Также добавьте local OPTIND OPTARG 07.08.2013
  • Спасибо. FUNCNAME работает. У меня все функции находятся в одном файле, так что это идеально подходит для расширения их во что-то полезное для других. 08.08.2013
  • @sigur, убедитесь, что вы цитируете "$usage" каждый, где его используете. 24.12.2016
  • Для чего нужен shift $((OPTIND - 1))? 22.07.2019
  • Это удалит все параметры из позиционных параметров, так что $ 1 будет первым аргументом, следующим за параметрами. Если бы вы писали функцию для ls и набрали ls -l -a /, тогда $ 1 будет / 22.07.2019

  • 2

    Первый аргумент сценария оболочки доступен как переменная $1, поэтому простейшей реализацией будет

    if [ "$1" == "-h" ]; then
      echo "Usage: `basename $0` [somestuff]"
      exit 0
    fi
    

    Но что сказал анубхава.

    29.03.2011
  • Вы должны иметь привычку заключать if в [[...]] для условных выражений, чтобы избежать неправильного синтаксического анализа переменной, source: github.com/bahamas10/bash-style-guide#bashisms 19.03.2017
  • Да, хотя OP не указывал bash, а [ является POSIX-совместимой версией. 20.03.2017
  • Примечание. Для использования внутри function: следует заменить exit 0 на return, если вы не хотите завершать работу оболочки после выполнения функции. (Я делал это раньше ????) 07.09.2017

  • 3

    вот часть, которую я использую для запуска сервера VNC

    #!/bin/bash
    start() {
    echo "Starting vnc server with $resolution on Display $display"
    #your execute command here mine is below
    #vncserver :$display -geometry $resolution
    }
    
    stop() {
    echo "Killing vncserver on display $display"
    #vncserver -kill :$display
    }
    
    #########################
    # The command line help #
    #########################
    display_help() {
        echo "Usage: $0 [option...] {start|stop|restart}" >&2
        echo
        echo "   -r, --resolution           run with the given resolution WxH"
        echo "   -d, --display              Set on which display to host on "
        echo
        # echo some stuff here for the -a or --add-options 
        exit 1
    }
    
    ################################
    # Check if parameters options  #
    # are given on the commandline #
    ################################
    while :
    do
        case "$1" in
          -r | --resolution)
              if [ $# -ne 0 ]; then
                resolution="$2"   # You may want to check validity of $2
              fi
              shift 2
              ;;
          -h | --help)
              display_help  # Call your function
              exit 0
              ;;
          -d | --display)
              display="$2"
               shift 2
               ;;
    
          -a | --add-options)
              # do something here call function
              # and write it in your help function display_help()
               shift 2
               ;;
    
          --) # End of all options
              shift
              break
              ;;
          -*)
              echo "Error: Unknown option: $1" >&2
              ## or call function display_help
              exit 1 
              ;;
          *)  # No more options
              break
              ;;
        esac
    done
    
    ###################### 
    # Check if parameter #
    # is set too execute #
    ######################
    case "$1" in
      start)
        start # calling function start()
        ;;
      stop)
        stop # calling function stop()
        ;;
      restart)
        stop  # calling function stop()
        start # calling function start()
        ;;
      *)
    #    echo "Usage: $0 {start|stop|restart}" >&2
         display_help
    
         exit 1
         ;;
    esac
    

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

    14.06.2015
  • если вы дадите пустую опцию -d; Разве это не бесконечный цикл? 17.01.2016
  • Почему вы выходите из 1 во вспомогательной функции? 01.08.2020

  • 4

    Для быстрого решения с одним вариантом используйте if

    Если у вас есть только один вариант для проверки, и он всегда будет первым вариантом ($1), то самым простым решением будет if с тестом ([). Например:

    if [ "$1" == "-h" ] ; then
        echo "Usage: `basename $0` [-h]"
        exit 0
    fi
    

    Обратите внимание, что для совместимости с posix = будет работать так же, как ==.

    Зачем цитировать $1?

    Причина, по которой $1 нужно заключить в кавычки, заключается в том, что если $1 нет, оболочка попытается запустить if [ == "-h" ] и завершится ошибкой, потому что == был дан только один аргумент, когда он ожидал два:

    $ [ == "-h" ]
    bash: [: ==: unary operator expected
    

    Для чего-то более сложного используйте getopt или getopts.

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

    В качестве краткого справочника мне нравится 60-секундное руководство по getopts.

    Вы также можете рассмотреть программу getopt вместо встроенной оболочки _ 18_. Он позволяет использовать длинные параметры и параметры после без аргументов (например, foo a b c --verbose, а не просто foo -v a b c). В этом ответе на Stackoverflow объясняется, как использовать GNU getopt.

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

    01.03.2013
  • Спасибо! Я с удовольствием использую getopts уже год, но я тоже посмотрю на getopt. 01.03.2013
  • К сожалению, ссылка на 60-секундный учебник по getopts мертва; похоже, что bashcurescancer.com больше нет. Вот ссылка на Версия Wayback Machine. 12.03.2014

  • 5

    Лучше использовать средство getopt в bash. Пожалуйста, посмотрите эти вопросы и ответы для получения дополнительной помощи: Использование getopts в сценарии оболочки bash для получения длинных и коротких параметров командной строки

    29.03.2011

    6

    я думаю, вы можете использовать для этого случай ...

    case $1 in 
     -h) echo $usage ;; 
      h) echo $usage ;;
    help) echo $usage ;;
    esac
    
    07.08.2014

    7

    Есть простой способ реализовать это без getopt или getopts:

    display_help() {
        # taken from https://stackoverflow.com/users/4307337/vincent-stans
        echo "Usage: $0 [option...] {start|stop|restart}" >&2
        echo
        echo "   -r, --resolution           run with the given resolution WxH"
        echo "   -d, --display              Set on which display to host on "
        echo
        # echo some stuff here for the -a or --add-options 
        exit 1
    }
    
    log() {
        echo "This is a log"
    }
    while [[ "$#" -gt 0 ]]; do
        case $1 in
            -h|--help) display_help; shift ;;
            -l|--log) log; shift ;;
            # ... (same format for other required arguments)
            *) echo "Unknown parameter passed: $1" ;;
        esac
        shift
    done
    
    06.04.2021
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..