Автоматическое расширение переменной внутри команды bash [[ ]]

Вы можете использовать sendmailили "sendmail look alike", предоставленный postfix/exim/....

/usr/sbin/sendmail -i -- $recipients < message_file

-i-не обрабатывать линии с ведущей точкой специально


Вы можете использовать более экзотические "sendmail look alike" (, например. предоставляетсяmsmtp)для отправки напрямую через другой smtp-хост без «общесистемной» конфигурации.
msmtpраспространяется в Debian, поэтому, вероятно, он будет включен в другие дистрибутивы Linux.

https://packages.debian.org/stretch/msmtp

Package: msmtp (1.6.6-1)
light SMTP client with support for server profiles

msmtp is an SMTP client that can be used to send mails from Mutt and probably other MUAs (mail user agents). It forwards mails to an SMTP server (for example at a free mail provider), which takes care of the final delivery. Using profiles, it can be easily configured to use different SMTP servers with different configurations, which makes it ideal for mobile clients.

13
04.12.2018, 03:11
2 ответа

Да, ваше наблюдение верно, расширение переменных выполняется для выражений, заключенных в двойные скобки [[ ]], поэтому вам не нужно ставить $перед именем переменной.

Это прямо указано в bashруководстве:

[[ expression ]]

(...) Word splitting and pathname expansion are not performed on the words between the [[ and ]]; tilde expansion, parameter and variable expansion, arithmetic expansion, command substitution, process substitution, and quote removal are performed.

Обратите внимание, что это не относится к версии с одной скобкой -[ ], так как [не является ключевым словом оболочки (синтаксисом ), а скорее командой (в bash, в которую она встроена.,другие снаряды могли использовать внешние, облицованные для испытаний ).

1
27.01.2020, 19:53

Причина в том, что -eqтребует арифметической оценки аргументов.

Арифметический оператор :-eq, -gt, -lt, -ge, -leи -neвнутри[[ ]](в ksh, zsh и bash )означает автоматическое расширение имен переменных как в языке c нет необходимости в ведущем $.

  • Для подтверждения мы должны изучить исходный код bash. Руководство не предлагает прямого подтверждения.

    Внутри test.cобработка арифметических операторов попадает в эту функцию:

    arithcomp (s, t, op, flags)
    

    Где sи t— оба операнда. Операнды передаются этой функции:

    l = evalexp (s, &expok);
    r = evalexp (t, &expok);
    

    Функция evalexpопределена внутри expr.c, которая имеет этот заголовок:

    /* expr.c -- arithmetic expression evaluation. */
    

    Итак, да, обе части арифметического оператора попадают (непосредственно )в вычисление арифметического выражения. Напрямую, без но, без если.


На практике с:

 $ x=3

Оба они терпят неудачу:

 $ [[ x = 4 ]] && echo yes || echo no
 no

 $ [[ x = 3 ]] && echo yes || echo no
 no

Правильно, xне расширяется и xне равно числу.

Однако:

 $ [[ x -eq 3 ]] && echo yes || echo no
 yes

 $ [[ x -eq 4 ]] && echo yes || echo no
 no

Переменная с именем xрасширяется (даже без $).

Это не происходит для […]в zsh или bash (это происходит в ksh ).


Это то же самое, что происходит внутри$((…)):

 $ echo $(( x + 7 ))
 10

И, пожалуйста, поймите, что это (очень )рекурсивно (, за исключением тире и тире):

 $ a=b b=c c=d d=e e=f f=3
 $ echo "$(( a + 7 ))" 
 10

А

И довольно рискованно:

 $ x='a[$(date -u)]'
 $ [[ x -eq 3 ]] && echo yes || echo no
 bash: Tue Dec  3 23:18:19 UTC 2018: syntax error in expression (error token is "Dec  3 23:18:19 UTC 2018")

Синтаксической ошибки можно легко избежать:

 $ a=3; x='a[$(date -u >/dev/tty; echo 0)]'

 $ [[ x -eq 3 ]] && echo yes || echo no
 Tue Dec  4 09:02:06 UTC 2018
 yes

Как говорится:очистите свой ввод

 $ [[ ${x//[^0-9]} -eq 3 ]] && echo yes || echo no
 no

конец


Оба (более старые )внешние/usr/bin/test(не встроенныеtest)и еще более старые и также внешние exprне расширяют выражения только целые числа(и, по-видимому, только десятичные целые):

 $ /usr/bin/test "x" -eq 3
 /usr/bin/test: invalid integer ‘x’

 $ expr x + 3
 expr: non-integer argument
9
27.01.2020, 19:53

Теги

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