Почему нельзя использовать несколько команд с || или && условная работа?

Код вызывает функцию с именем clone_file , если для параметра reflink установлено значение «always» или «auto», и возвращается к копированию, если reflink имеет значение «always» (и переходит непосредственно к копированию, если рефссылка выключена). clone_file вызывает BTRFS_IOC_CLONE ioctl . Таким образом, нет никакой проверки, поддерживает ли система копирование при записи, она просто пытается использовать метод BTRFS.

12
03.04.2019, 23:40
4 ответа

Это:

[ "${#}" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1

не является:

[ "${#}" -eq 1 ] || { echo "Invalid number of arguments, expected one."; exit 1; }

Но вместо этого:

{ [ "${#}" -eq 1 ] || echo "Invalid number of arguments, expected one."; } 
exit 1

Ваш сценарий завершается независимо от того, сколько аргументов вы ему передали.

17
27.01.2020, 19:54

Я часто видел это как проверку пустой строки:

if [ "x$foo" = "x" ]; then...
-1
27.01.2020, 19:54

Обратите внимание, что ваша строка

[ "${#}" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1

это то же самое, что и

[ "${#}" -eq 1 ] || echo "Invalid number of arguments, expected one."
exit 1

(;без кавычек в большинстве случаев можно заменить символом новой строки)

Это означает, что оператор exit 1всегда выполняется независимо от того, сколько аргументов было передано сценарию. Это, в свою очередь, означает, что сообщение The given argument is empty.никогда не будет напечатано.

Чтобы выполнить более одного оператора после теста с использованием «короткого -синтаксиса схемы», сгруппируйте операторы в {...; }. Альтернативой является использование правильного оператора if(, который, ИМХО, выглядит чище в сценарии):

if [ "$#" -ne 1 ]; then
    echo 'Invalid number of arguments, expected one.' >&2
    exit 1
fi

У вас такая же проблема со вторым тестом.


Относительно

[ -z "" ] && echo A || echo B

Это будет работать для данного примера, но общий

some-test && command1 || command2

не будет ли не таким же, как

if some-test; then
    command1
else
    command2
fi

Наоборот, это больше похоже на

if ! { some-test && command1; }; then
    command2
fi

или

if some-test && command1; then
    :
else
    command2
fi

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

36
27.01.2020, 19:54

Один из способов сделать его более читабельным — определить dieфункцию (а-ля perl), например:

die() {
  printf >&2 '%s\n' "$@"
  exit 1
}

# then:

[ "$#" -eq 1 ] || die "Expected one argument, got $#"

[ -n "$1" ] || die "Empty argument not supported"

Вы можете добавить дополнительные навороты, такие как цвета, префикс, номер строки... если это необходимо.

8
27.01.2020, 19:54

Теги

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