Извините, если это глупый вопрос с очевидным ответом, лежащим на какой-то странице руководства. Я не нашел там хорошей информации.
Есть задача для начинающих, где даны два ненулевых целых числа, и вам нужно написать скрипт для вывода их суммы, разности, произведения и частного, каждое на новой строке.
Конечно, есть чрезвычайно простые способы сделать это в одну строку, но вот что я в итоге сделал
read x
read y
printf "$(( "$x" + "$y" ))\n"
printf "$(( "$x" - "$y" ))\n"
printf "$(( "$x" * "$y" ))\n"
printf "$(( "$x" / "$y" ))\n"
Хотя это работает нормально, если x и y положительные, а x больше y, я получаю сообщение об ошибке, когда любая из операций должна давать отрицательный результат (т. е. когда либо x, либо y отрицательны, либо x меньше y).
Например, если x равно 50, а y равно 20, я получаю
70
30
1000
2
Но если x равно 20, а y 50
70
./twon: line 3: printf: -3: invalid option
printf: usage: printf [-v var] format [arguments]
1000
0
Аналогично, если я попробую отрицательные числа, пусть x=-50 и y=20
./twon: line 3: printf: -3: invalid option
printf: usage: printf [-v var] format [arguments]
./twon: line 4: printf: -7: invalid option
printf: usage: printf [-v var] format [arguments]
./twon: line 5: printf: -1: invalid option
printf: usage: printf [-v var] format [arguments]
./twon: line 6: printf: -2: invalid option
printf: usage: printf [-v var] format [arguments]
Однако, если я заменю команду printf
на echo -e
read x
read y
echo -e "$(( "$x" + "$y" ))"
echo -e "$(( "$x" - "$y" ))"
echo -e "$(( "$x" * "$y" ))"
echo -e "$(( "$x" / "$y" ))"
все работает нормально, и я получаю все результаты операций для любой пары целых чисел.
Что мне здесь не хватает?
См. раздел ИСПОЛЬЗОВАНИЕ ПРИЛОЖЕНИЯ в спецификация POSIX для echo
, в котором описывается, как использовать printf
в качестве замены (и настоятельно рекомендуется это делать). Вы увидите, что printf
эквивалентен традиционному XSI echo
(который заменяет, скажем, \t
на буквальную вкладку) printf "%b\n" "$*"
.
@CharlesDuffy тьфу, не могу поверить, что это было так просто. Большое спасибо. модераторы не стесняйтесь закрывать это.
Используйте это вместо этого:
printf '%s\n' "$(( x / y ))"
Первый аргумент
printf
— это строка формата, а не буквальные данные.printf '%s\n' "anything"
работает с любым значениемanything
(включая значения, которые вы не можете надежно напечатать с помощьюecho
).