Я хочу, чтобы мой 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
Что я делаю неправильно?
Как и любая другая простая команда, [ ... ]
или 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.
Это должно быть полезно, если вам нужно будет объединить его с другими функциями [[ ]]
.
Это может быть хорошей идеей использовать арифметические выражения, если вы имеете дело с числами.
if (( $# != 1 )); then
echo "Illegal number of parameters"
fi
В []:! =, =, ==... являются операторами сравнения строк и -eq, -gt... являются арифметическими двоичными.
Я бы использовал:
if [ "$#" != "1" ]; then
Или:
if [ $# -eq 1 ]; then
==
на самом деле не документировано, что случается работать с GNU test
. Случается также работать с FreeBSD test
, но не может работать на Foo test
. Единственное стандартное сравнение - =
(только к вашему сведению).
Если вас интересует только 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
Простой один лайнер, который работает, может быть выполнен с использованием:
[ "$#" -ne 1 ] && ( usage && exit 1 ) || main
Это разбивается на:
Думает заметить:
exit 1
будет применяться только к контексту подоболочки, делая его просто синонимом ( usage; false )
. Я не являюсь поклонником такого упрощения, когда дело доходит до разбора опций, но вы можете использовать { usage && exit 1; }
вместо. Или, возможно, просто { usage; exit 1; }
Если вы хотите быть в безопасности, я рекомендую использовать 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
Вы должны добавить пробелы между условиями теста:
if [ $# -ne 1 ];
then echo "illegal number of parameters"
fi
Надеюсь, это поможет.
test
. Это название стандартной команды Unix, вы бы не хотели ее скрывать.