Знание должно быть доступно!

Путь /ОС/FreeBSD

Код возврата - кровь боя

  • 0 - успех.

  • !=0 - провал.
    Команда не болтает - она возвращает код. Смотри echo $? после выстрела.

    Тактика &&

    A && B - B идёт только если A победил (код 0).
    Итоговый код - от последней выполненной команды.

jexec traefik true && echo "OK"   # печатаем OK
jexec traefik false && echo "OK"  # молчим, потому что A упал

Тактика ||

A || B - B идёт только если A свалился (код ≠ 0).
Итоговый код - от последней выполненной команды.

В связке: (A && B) || C

&& и || одинакового приоритета, идут слева направо.
A && B || C == (A && B) || C.

  • Если A упалB не бежит → идёт C.

  • Если A прошёл, но B упал → идёт C.

  • Если A прошёл и B прошёлC не нужен.

jexec traefik sh -c 'sockstat -46l | awk "{print $6}" | grep -q ":80$"' \
  && echo "OK: LISTEN 80" \
  || echo "FAIL: нет LISTEN"

Ложный "тернарник" и ловушка

Шаблон A && B || C не равен «если A, то B, иначе C», потому что если B упадёт, сыграет C - даже при успехе A.
Жёстко и безопасно так:

if A; then
  B
else
  C
fi

Или группируй, когда нужно несколько команд:

A && { B1; B2; } || { C1; C2; }

Негация ! - инвертор

! CMD переворачивает код возврата.

! grep -q ':80$' sockets.txt && echo "нет LISTEN"  # тишина = найдено; вывод = не найдено

Пайпы и кто отвечает за провал

В пайпе A | B | C код возврата - от последней команды (C).
Значит, если ставишь grep -q в конце, ты проверяешь именно его результат - то, что и нужно при поиске.

sockstat -46l | awk '{print $6}' | grep -q ':80$' && echo OK || echo FAIL

Нужно знать провал любого звена пайпа? Используй оболочку с pipefail (в FreeBSD /bin/sh это есть):
set -o pipefail - код пайпа станет провалом, если любой элемент упал.
(Если нет - обходи через поэтапные проверки или if.)

В бою с set -e

set -e = любой провал рвёт скрипт.
Чтобы сознательно поглотить провал, ставь «пожиратель»:

команда || true       # или коротко: || :

Пример: хотим просто проверить, без смерти скрипта:

set -e
if jexec traefik sh -c 'sockstat -46l | awk "{print $6}" | grep -q ":80$"'; then
  echo "OK"
else
  echo "FAIL"
fi

Боевое применение (живой пример)

jexec traefik sh -c 'sockstat -46l | awk "{print $6}" | grep -q ":80$"' \
  && logger -t check_traefik "OK: LISTEN :80" \
  || { logger -t check_traefik "DOWN: :80 - рестарт"; jexec traefik service traefik restart; }

Если порт найден → пишем OK.

Если нет → лог и рестарт.

Быстрая разведка кодов:

CMD; echo $?     # покажет код возврата CMD

Приказ: помни матчасть.

  • && - бежим дальше только после победы.

  • || - страхуем провал.

  • Группируй { ...; }, когда цепляешь несколько команд.

  • Для "по-настоящему если-иначе" - if/else.
    Код - клинок. Бездумные тернарники - кость под ногами.