Вопрос по command-line-arguments, idioms, parameters, bash, conditional-statements – Идиоматический способ проверить, не даны ли позиционные параметры?

4

Какой самый идиоматичный способ в Bash проверить, не заданы ли позиционные параметры? Есть так много способов проверить это, интересно, есть ли один предпочтительный способ.

Некоторые способы:

((! $# )) # check if $# is 'not true'
(($# == 0)) # $# is 0
[[ ! [email protected] ]] # [email protected] is unset or null
IMO, вы должны пересмотреть, что именно вы считаете «без позиционных параметров». Например, вы рассматриваете один нулевой аргумент (your-script '') верный аргумент? Michał Górny
Последний будет ложно положительным наscript '' (нулевой аргумент). Dennis Williamson

Ваш Ответ

5   ответов
4

Для меня классический способ это:

[[ $# -eq 0 ]]
Обновлено для использования[[ ... ]]что действительно лучше.
На самом деле,[ также является встроенным в bash (который переопределяет / bin / [), поэтому их скорость должна быть примерно одинаковой. Самая большая разница в том, что[[ ... ]] избегает некоторой сложности анализа со строками, которая здесь не применима.
+1 но используй[[ ... ]] вместо.[[ ... ]] это встроенный в Bash в то время как[ ... ] вызывает внешнюю тестовую утилиту. IOW, первый быстрее.
[[ это не встроенное, это ключевое слово. контрастироватьtype [ сtype [[, Это означает, что он был введен ранее в расширении командной строки и почему, например, вам не нужно заключать в кавычки переменные со встроенными пробелами.
1

: ${@?no positional parameters}

напечатает "нет позиционных параметров" к стандартной ошибке (и выйти из неинтерактивной оболочки), если[email protected] не установлен

В противном случае я не знаю каких-либо лучших вариантов, чем один из различных способов проверки,$# это 0.

-1

что если нет позиционных параметров, то также нет первого параметра:

[[ -z $1 ]]
test -z "$1"
[ -z "$1" ]

Это просто немного легче для читателя. Конечно, это работает только тогда, когда предположение о том, что первый параметр не может быть пустой строкой, является верным.

Я думаю ты имел ввиду[ -n "$1" ], Флаг -n проверяет, что длина STRING отлична от нуля.
То же самое, имеет значение только то, как вы используете результат.
Это не меняет того факта, что это не проверяет наличие позиционных параметров.
Конечно, но так как это мой код, я бы не стал использовать этот метод, если бы знал, что пустая строка является допустимым параметром.
Это терпит неудачу, если первый параметр - пустая строка:foo "" 2.
1
Use Sensible Semantics

н поступить иначе, вы, вероятно, просто хотите определить длину списка параметров.

# Is length of parameter list equal to zero?
[ $# -eq 0 ]

Однако вы, безусловно, можете использовать любой оператор расширения или сравнения параметров, который выражает намерение вашего кода. Нет правильного способа сделать это, но вы, возможно, захотите рассмотреть вопрос о том, семантика вашего тестаportable.

Food for Thought

Это не условное выражение, которое по сути важно. Что важно, так этоwhy ты хочешь знать. Например:

set -e
foo="$1"
shift

# $2 is now $1 (but only if the line is reached)
echo "$1"

В этом случае длина списка параметров никогда не проверяется напрямую. Первый параметр просто назначается (даже если он может быть не установлен), а затем оболочка выдает ошибку и завершает работу, когда вы пытаетесь сместить список параметров. Этот код говорит: «Я просто ожидаю, что параметры будут там; Мне не нужно явно их проверять. & Quot;

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

1

Вот наиболее логичный способ:

[ ! [email protected] ]

Он основан на одном правиле:

[ ] # this returns 1

Ну тогда,

[ ! ] # this returns 0

Остальное очевидно: $ @ - это специальный параметр, который расширяется до списка всех позиционных параметров.

Тестовое задание: (Это будет работать, даже если вы добавите в него пару пустых строк ("quot;" quot; "quot;").)

if [ ! [email protected] ]; then
    printf 'Note: No arguments are given.'
fi

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