Выполняются ли математические операции оболочки в подоболочке?

Согласно этому другому ответу
Что означают числа в цепочках INPUT,FORWARD,OUTPUT в конфигурационном файле iptables?
Цифры в скобках — это статистические значения, которые команда iptables-saveсчитывает с работающего брандмауэра и представляет трафик , который был отфильтрован цепочкой.

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

*filter
:FORWARD ACCEPT [0:0]

просто означают, что эта Цепь никогда не использовалась. Вероятно, потому что у него нет никакого правила.

1
04.02.2020, 21:47
2 ответа

$(cmd arg)запускается cmdв среде подоболочки, и его вывод (за вычетом завершающих символов новой строки )становится результатом расширения.

(cmd arg)выполняется в подоболочке без изменения вывода.

Таким образом, $((cmd arg))будет таким же, как $(cmd arg), но с дополнительным слоем подоболочки, за исключением того, что это не так.

$((...))— это отдельная форма расширения, исходящая из оболочки Korn. В оболочке Korn ((arithmetic expression))оценивает арифметическое выражение (, которое следует синтаксису, очень похожему на синтаксис C ), а статус выхода отражает, разрешается ли выражение в 0 или не -в ноль.

Это позволяет делать такие вещи, как:

if ((var < 10)); then
 ...
fi

Что делает его очень похожим на C.

$используется для введения разложений . Точно так же, как $(cmd)подобен (cmd), за исключением того, что расширяет до результата cmd, $((arith))подобен ((arith)), за исключением того, что он расширяет до результата вычисление арифметического выражения.

POSIX, чей shв основном основан на ksh88, указал $((...)), но не ((...)). На самом деле, в более раннем черновике это было $[...], поэтому вы обнаружите, что bashи zshподдерживают $[...]в качестве альтернативы $((...)).

IIRC, основная причина, по которой POSIX изначально думал указать его как $[...], заключается в том, что $((...))конфликтует с $((cmd arg)), подоболочкой внутри подстановки команд.

Вы обнаружите, что большинство оболочек правильно идентифицируют $((echo x; echo y) | (tr xy ab))как , а не как арифметическое расширение, но не $((cmd arg)).В любом случае $((cmd))предназначен для расширения до арифметического значения переменной $cmd, а не до вывода cmd.

Соответствующий текст спецификации POSIX содержит:

The syntax of the shell command language has an ambiguity for expansions beginning with "$((", which can introduce an arithmetic expansion or a command substitution that starts with a subshell. Arithmetic expansion has precedence; that is, the shell shall first determine whether it can parse the expansion as an arithmetic expansion and shall only parse the expansion as a command substitution if it determines that it cannot parse the expansion as an arithmetic expansion. The shell need not evaluate nested expansions when performing this determination. If it encounters the end of input without already having determined that it cannot parse the expansion as an arithmetic expansion, the shell shall treat the expansion as an incomplete arithmetic expansion and report a syntax error. A conforming application shall ensure that it separates the "$(" and '(' into two tokens (that is, separate them with white space) in a command substitution that starts with a subshell. For example, a command substitution containing a single subshell could be written as:

ksh((...))также конфликтует с вложенными подоболочками. Хотя POSIX не определяет ((...)), он допускает поведение ksh.

На практике при вложении субоболочек и/или cmdsubst вы должны обязательно включать пробелы между скобками:

echo "$( (...) )"
( (a; b) | (c;d) )
7
28.04.2021, 23:24

Вот демо, которое не работает в подоболочке :вы можете изменять переменные в арифметическом выражении:

$ x=5; echo "$(( x *= 2 ))"; echo "$x"
10
10

Если бы это была подоболочка, echo $xвывел бы 5.

При использовании арифметики оболочки имейте в виду, что не все оболочки поддерживают приращение до -и после -;dash(значение по умолчанию /bin/shв текущих версиях Debian и производных )интерпретирует $(( ++i ))как $(( +(+i) ))и НЕ увеличивает переменную i.

4
28.04.2021, 23:24

Теги

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