Поскольку cp
является командой пользовательского пространства, это не влияет на целостность файловой системы.
Вы, конечно, должны быть готовы к тому, что хотя бы один файл не будет скопирован полностью, если вы убьете работающую cp
программу.
Так и должно быть
some_func() {
echo "$(( 3 + 5 ))"
}
[ "$(some_func)" -lt 10 ]
Почему это не удалось
$(some_func)
расширяется до вывода функции*(за вычетом ее завершающей новой строки ), которая, однако, ничего не выводит. Следовательно, тест становится
[ -lt 10 ]
В своих самых основных формах тест [
принимает от 1 до 3 параметров . Поскольку выше есть 2 параметра, Bash ожидает, что 1-й будет унарным оператором. -lt
является двоичным, отсюда и сообщение об ошибке.
Если бы вы процитировали соответствующее расширение с
[ "$(some_func)" -lt 10 ]
Ошибка будет "ожидается целочисленное выражение", потому что тест будет иметь пустую строку:
[ "" -lt 10 ]
И, кроме нетривиальных -обстоятельств , && true
является излишним.
*Поскольку расширение не заключено в кавычки, вывод также подвергается разбиению на слова и расширению имени файла . Они не должны играть роли в данном примере, пока $IFS
не было изменено по сравнению со значением по умолчанию.
$(cmd)
получает стандартный вывод из cmd
¹, поэтому для расширения до результата вам нужно от cmd
до вывести это:
some_func() {
echo "$(( 3 + 5 ))"
}
[ "$(some_func)" -lt 10 ]
, как уже сказали другие. Однако это означает, что some_func
запускается в среде подоболочки, поэтому любое изменение переменных или чего-либо еще будет впоследствии потеряно.
Например, нет смысла:
counter=0
incr() { echo "$((++counter))"; }
while [ "$(incr)" -le 10 ]...
, так как $(incr)
всегда будет расширяться до 1 (, так как counter
будет увеличиваться только в подоболочке ).
Чтобы функция возвращала числовой результат посредством арифметического вычисления , вам потребуется оболочка с поддержкой математических функций , таких как ksh93
или zsh
. bash
не годится.
Вzsh
:
counter=0
incr() (( ++counter ))
functions -M incr
while (( incr() <= 10 )); do
print $counter
done
Вksh93
:
function.sh.math.incr i {
# ksh93 functions must take at least one argument
((.sh.value = (counter += i) ))
}
while (( incr(1) <= 10 )); do
print "$counter"
done
Другой альтернативой в ksh93 или последних версиях mksh является использование форм подстановки команд, которые не вводят подоболочки:
counter=0
function incr { print "$(( ++counter ))"; }
while [ "${ incr; }" -le 10 ]; do
print "$counter"
done
Или вmksh
:
counter=0
incr() (( REPLY = ++counter ))
while [ "${| incr; }" -le 10 ]; do
print "$counter"
done
В любой оболочке POSIX, включая bash
, вы всегда можете вернуть значение в предопределенной переменной ($REPLY
, которая обычно используется для этого):
counter=0
incr() { REPLY=$(( counter += 1 )); }
while incr; [ "$REPLY" -le 10 ]; do
echo "$counter"
done
Вы найдете более подробную информацию в этом ответе на другой вопрос и ответ о функции mksh valsub
¹ лишен завершающих символов новой строки, а в случае bash
— символов NUL, а здесь, поскольку вы забыли кавычки, с учетом разделения + подстановки