env -i
выполняет указанную команду с пустым окружением.
bash -c ...
выполняет аргумент опции -c
(опция ...
) в виде фрагмента кода bash.
bash -c 'echo $SHELL $HOME $USER'
эквивалентно echo $SHELL $HOME $USER
, поскольку запуск bash не изменяет эти переменные (по крайней мере, пока они изначально установлены).
env -i bash -c 'echo $SHELL $HOME $USER'
запускает bash
с аргументами -c
и echo $SHELL $HOME $USER
, и с пустым окружением. Когда bash запускается, он устанавливает некоторые переменные оболочки, включая SHELL
(которая устанавливается только как переменная оболочки, а не экспортируется в окружение любой дочерней программы, которую bash может запустить). Таким образом, когда bash разбирает и расширяет команду echo $SHELL $HOME $USER
, переменные HOME
и USER
не установлены, но SHELL
установлен в /bin/sh
(я не знаю, почему bash так делает), и эта команда выводит /bin/sh
, за которым следуют два пробела.
Одинарные кавычки вокруг аргумента bash -c
гарантируют, что текст в кавычках не будет расширен оболочкой, из которой вы запускаете env -i bash -c '...'
, так что текст передается подпроцессу bash как есть.
$ x
- строка. Пользователь может ввести что угодно, это не обязательно число. Проверка ввода происходит после ввода . Вы должны проверить, является ли это целым числом, а затем вы можете выполнить арифметическое сравнение. Например,
read x
#validate if it is an integer
[[ "$x" =~ -?[0-9]+ ]] || echo error
#validate range (this is better done algebraically, not with string manipulation)
(( x >= -100 && x <= 100 )) || echo error
# carry on
, кстати, выражение арифметической оценки в $ ((...))
может использовать имена переменных, а не расширения переменных. Просто напишите $ ((x + y))
.
Решение для пуритан:
x=$(awk '/^-?[0-9]+\s*$/{ if ($1<=100 && $1>=-100){ print; exit; } } { exit 1; }') || echo error
В этом случае awk
читает ввод, а не оболочку, но вы также можете сделать это с помощью read
, а затем отфильтровать результат. Вместо эхо-ошибки
вы можете использовать выражение в цикле (который повторно запрашивает у пользователя другой ввод) или просто выйти с помощью exit 1
.
Вы не можете сделать это , пока не прочитали x
- вы еще не читали это. Как можно проверить неизвестное? Единственное решение - получить данные, а затем протестировать их. Однако это можно сделать:
case ${#x}${x##?*[!0-9]*} in
(?|[!1-4]*|4[!-]*|1-*|?[!-0-9]*) ! :;;
(*) echo "$(( x + y ))";;esac