Проверьте количество аргументов, переданных в Bash script

Я хочу, чтобы мой Bash script печатал сообщение об ошибке, если счетчик требуемых аргументов не выполняется.

Я попробовал следующий код:

#!/bin/bash
echo Script name: $0
echo $# arguments 
if [$# -ne 1]; 
    then echo "illegal number of parameters"
fi

По какой-то неизвестной причине у меня есть следующая ошибка:

test: line 4: [2: command not found

Что я делаю неправильно?

Ответ 1

Как и любой другой простой команде, [ ... ] или test требуют пробелов между аргументами.

if [ "$#" -ne 1 ]; then
    echo "Illegal number of parameters"
fi

Или

if test "$#" -ne 1; then
    echo "Illegal number of parameters"
fi

Предложения

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

[[ $# -ne 1 ]]

Он также имеет некоторые другие функции, такие как группировка условий без кавычек, сопоставление с образцом (расширенное сопоставление с extglob) и сопоставление с регулярным выражением.

В следующем примере проверяется, допустимы ли аргументы. Это допускает один или два аргумента.

[[ ($# -eq 1 || ($# -eq 2 && $2 == <glob pattern>)) && $1 =~ <regex pattern> ]]

Для чисто арифметических выражений использование (( )) для некоторых может быть еще лучше, но они все еще возможны в [[ ]] с его арифметическими операторами, такими как -eq, -ne, -lt, -le, -gt или -ge, поместив выражение в виде строкового аргумента:

A=1
[[ 'A + 1' -eq 2 ]] && echo true  ## Prints true.

Это может быть полезно, если вам потребуется объединить его с другими функциями [[ ]].

Выход из сценария

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

-1, хотя и принят Bash в качестве аргумента exit, явно не задокументирован и не может быть использован в качестве общего предложения. 64 также является наиболее формальным значением, поскольку оно определено в sysexits.h с помощью #define EX_USAGE 64 /* command line usage error */. Большинство инструментов, таких как ls, также возвращают 2 при неверных аргументах. Я также использовал для возврата 2 в своих скриптах, но в последнее время я больше не заботился об этом, а просто использовал 1 во всех ошибках. Но давайте просто разместим здесь 2, поскольку он наиболее распространенный и, вероятно, не зависит от ОС.

if [[ $# -ne 1 ]]; then
    echo "Illegal number of parameters"
    exit 2
fi

Ссылки

Ответ 2

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

if (( $# != 1 )); then
    echo "Illegal number of parameters"
fi

Ответ 3

В []:! =, =, ==... являются операторами сравнения строк и -eq, -gt... являются арифметическими двоичными.

Я бы использовал:

if [ "$#" != "1" ]; then

Или:

if [ $# -eq 1 ]; then

Ответ 4

Если вас интересует только bailing, если отсутствует какой-либо аргумент, Замена параметров великолепна:

#!/bin/bash
# usage-message.sh

: ${1?"Usage: $0 ARGUMENT"}
#  Script exits here if command-line parameter absent,
#+ with following error message.
#    usage-message.sh: 1: Usage: usage-message.sh ARGUMENT

Ответ 5

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

[ "$#" -ne 1 ] && ( usage && exit 1 ) || main

Это разбивается на:

  • проверить переменную bash для размера параметров $# не равна 1 (наш номер подкоманд)
  • если true, тогда функция use() вызова и выход со статусом 1
  • else вызов функции main()

Думает заметить:

  • use() может быть просто эхом "$ 0: params"
  • main может быть длинным script

Ответ 6

Ознакомьтесь с этой таблицей bash, она может вам помочь.

Чтобы проверить длину переданных аргументов, вы используете "$#"

Чтобы использовать массив переданных аргументов, вы используете "[email protected]"

Пример проверки длины и итерации:

myFunc() {
  if [[ "$#" -gt 0 ]]; then
    for arg in "[email protected]"; do
      echo $arg
    done
  fi
}

myFunc "[email protected]"

Это помогло мне, но мне не хватало нескольких вещей для меня и моей ситуации. Надеюсь, это кому-нибудь поможет.

Ответ 7

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

Вот небольшой пример:

    while getopts "x:c" opt; do
      case $opt in
        c)
          echo "-$opt was triggered, deploy to ci account" >&2
          DEPLOY_CI_ACCT="true"
          ;;
            x)
              echo "-$opt was triggered, Parameter: $OPTARG" >&2 
              CMD_TO_EXEC=${OPTARG}
              ;;
            \?)
              echo "Invalid option: -$OPTARG" >&2 
              Usage
              exit 1
              ;;
            :)
              echo "Option -$OPTARG requires an argument." >&2 
              Usage
              exit 1
              ;;
          esac
        done

подробнее см. здесь http://wiki.bash-hackers.org/howto/getopts_tutorial

Ответ 8

Здесь простые строки, чтобы проверить, задан ли только один параметр, иначе выйдите из скрипта:

[ "$#" -ne 1 ] && echo "USAGE $0 <PARAMETER>" && exit

Ответ 9

Вы должны добавить пробелы между условиями теста:

if [ $# -ne 1 ]; 
    then echo "illegal number of parameters"
fi

Надеюсь, это поможет.