новые строки и переменная bash

Я не думаю, что на самом деле существует встроенный стандарт, но есть несколько вещей, которые вы можете использовать в systemd.

ExecStartPre=

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

Если какая-либо из этих команд (без префикса «-») завершается ошибкой, остальные не выполняются, и устройство считается неисправным.

Restart=on-failure

Настраивает, должна ли служба быть перезапущена, когда процесс службы завершается, завершается или истекает тайм-аут.

Если установлено значение «при сбое», служба будет перезапущена, когда процесс завершается с ненулевым кодом выхода, завершается по сигналу (в том числе по дампу ядра, но исключая вышеупомянутые четыре сигнала), когда операция ( например, перезагрузка службы) истекает, и когда срабатывает настроенный тайм-аут сторожевого таймера.


Команды считаются неудачными, если они возвращают ненулевые коды выхода, поэтому, установив для ExecStartPre что-то, что доказывает, что ваш интерфейс работает, вы можете быть уверены, что вашей службе это потребуется.

Некоторые примеры:

ExecStartPre=/usr/bin/ping -c 1 ${SAN_IP}

ExecStartPre=/usr/sbin/iscsiadm -m session

Мне лично нравится вариант iscsiadm для вашего варианта использования. Если есть соединения iscsi, возвращаемое значение равно 0, в противном случае возвращается 21 (что приведет к сбою службы). Вариант ping может работать для более широкого спектра применений, но я бы сказал, что в большинстве случаев вы можете найти более подходящую команду для проверки состояния сети. Вы даже можете попробовать использовать ssh, если у вас настроены ключи для проверки вещей на другом хосте.

Дело в том, что ExecStartPre может позволить вам сделать так, чтобы ваша служба не работала на основе любых команд.Просто убедитесь, что любая используемая вами команда будет возвращать ненулевые коды выхода, когда вы этого хотите (например, cat при открытии пустого файла возвращает 0, тогда как cat при открытии не -существующий файл возвращает 1)


После некоторого размышления и комментария спрашивающего я бы сказал, что лучший способ определить сложное условие для службы — это создать другую службу, от которой она будет зависеть.

Создайте новую службу, которая использует команду для проверки состояния в качестве ExecStart. Дайте ему Restart=on-failure. Затем сделайте исходную службу Require и After.

Пример ExecStartPre, который я использовал выше, как бы искажает его первоначальную цель, которая заключалась в настройке вещей для правильной работы службы. Он все еще может применяться, и знания по-прежнему полезны, поэтому я оставляю их нетронутыми.

0
15.03.2018, 23:53
2 ответа

В:

cat test.txt | while read i; do echo $i; done

Вам удалось втиснуть довольно много плохих приемов написания сценариев оболочки:

Хотя я, вероятно, сначала должен был упомянуть Почему использование цикла оболочки для обработки текста считается плохой практикой? .

Попробуйте, например, ввести такой ввод:

-n
/*/*/*/../../../*/*/*
  foo\
bar

Если вам действительно нужно использовать цикл оболочки, это, вероятно, должно быть что-то вроде:

{
while IFS= read <&3 -r i; do
  printf '%s\n' "$i" || exit
done
[ -z "$i" ] || printf %s "$i" || exit
} 3< test.txt

В

for i in $(cat test.txt); do echo $i; done

Это заменяет плохую практику другим. Здесь у вас есть веская причина оставить $ (cat test.txt) без кавычек: вам нужна разделенная часть оператора split + glob, но вы забыли указать, что вы хотите разделить и чтобы отключить глобальную часть.

IFS='
' # split on newline only. The default value of $IFS
  # contains space, tab and newline which explains why you see
  # one word per line
set -o noglob # disable glob
for i in $(cat test.txt); do
  printf '%s\n' "$i" || exit
done

Обратите внимание, что по-прежнему будут пропускаться пустые строки, и при этом выполняется чтение и сохранение содержимого файла в памяти (несколько раз) перед запуском цикла.

5
28.01.2020, 02:15

Ответ заключается в том, что $ (command) расширяется до необработанного вывода команды, для которого ваша оболочка затем выполнит обычное разделение слов. Указанное разделение состоит из любых пробелов, которые считаются разделителями слов.

Вы также делаете две разные вещи с текстом; в одном вы анализируете его с помощью read (который работает с вводом line , а не с вводом word ], а в другом вы повторяете вывод $ (cat) в цикле for . Вы, вероятно, можете получить аналогичные результаты с помощью IFS = '\ n' for i в $ (cat test.txt); do echo " $ i "; done .

1
28.01.2020, 02:15

Теги

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