Код вызывает функцию с именем clone_file
, если для параметра reflink установлено значение «always» или «auto», и возвращается к копированию, если reflink имеет значение «always» (и переходит непосредственно к копированию, если рефссылка выключена). clone_file
вызывает BTRFS_IOC_CLONE
ioctl . Таким образом, нет никакой проверки, поддерживает ли система копирование при записи, она просто пытается использовать метод BTRFS.
Это:
[ "${#}" -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
Ваш сценарий завершается независимо от того, сколько аргументов вы ему передали.
Я часто видел это как проверку пустой строки:
if [ "x$foo" = "x" ]; then...
Обратите внимание, что ваша строка
[ "${#}" -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
То есть, если тест или первая команда завершатся неудачно, выполняется вторая команда, что означает, что она потенциально может выполнить все три задействованных оператора.
Один из способов сделать его более читабельным — определить die
функцию (а-ля perl
), например:
die() {
printf >&2 '%s\n' "$@"
exit 1
}
# then:
[ "$#" -eq 1 ] || die "Expected one argument, got $#"
[ -n "$1" ] || die "Empty argument not supported"
Вы можете добавить дополнительные навороты, такие как цвета, префикс, номер строки... если это необходимо.