Prostrelov писал(а): ↑13.05.2013 09:46
sgfault, а вы не могли бы прокомментировать эту строку:
Код: Выделить всё
tee /etc/rsyslog/pipe_logger </etc/rsyslog/dmzfifo_error >> /var/log/nginx/error.log &
я что-то никак не могу уловить что в ней происходит. я заранее добавил в неё пути что бы не смущало обращение к пайпам как к скриптам через "./".
По тем манам что находил у tee синтаксис довольно простой: tee [ПАРАМЕТР] [ФАЙЛ]. Параметры мы не использовали. Но видимо использовали ряд перенаправлений.
По этому что бы не гадать хотелось бы услышать что мы и как перенаправляем <>> такими символами.
Как вы, видимо, уже прочитали, tee читает из стандартного ввода (stdin) и пишет в стандартный вывод (sdout) и в файл, переданный как аргумент командной строки. Теперь осталось лишь найти, что есть что.
'/etc/rsyslog/pipe_logger' - это файл, в который пишет tee (в данном примере - пайп),
'</etc/rsyslog/dmzfifo_error' - это перенаправление стандартного ввода (stdin) на ввод из файла (в данном случае тоже пайп),
'>> /var/log/nginx/error.log' - это перенаправление стандартного вывода (stdout) в файл.
'&' - запуск команды в background (асинхронно).
На самом деле в этом примере есть более интересная вещь - wait. Точнее, сейчас я понял, что не могу объяснить зачем он нужен, и уже не уверен нужен ли вообще. Если пайп dmzfifo_error читает только один процесс (допустим, tee), то разницы есть он или нет не должно быть никакой: tee в background-е ждет, когда что-то появится в dmzfifo_error, а logger ждет пока что-то появится в pipe_logger. Когда что-то появляется в dmzfifo_error, tee все это читает, отправляет в error.log и pipe_logger и завершается, logger, соответственно, читает pipe_logger и тоже завершается и цикл продолжается.
Но если по каким-либо причинам dmzfifo_error читает несколько процессов (допустим, того же tee), то все становится намного интереснее. Сообщения из пайпа, как я понимаю, достанутся кому-то одному. Если в цикле стоит wait, то цикл будет ждать именно тот процесс, который он запустил, и если сообщения достанутся другому, то скрипт зависнет навсегда, тк даже если нужный tee успеет прочесть позже какое-то сообщение, он не завершится до тех пор, пока logger не прочитает из pipe_logger. А этого не произойдет, тк logger с этого прохода цикла уже отработал (использовав результат другого tee, который тоже писал в pipe_logger).
Те, если мое рассуждение правильное, wait может все повесить. Но в тот раз.. в тот раз я его добавил потому, что каким-то образом у меня получился цикл, который не останавливался: он запускал все больше и больше процессов. Сейчас я не могу это воспроизвести. Может, это было из-за какой-то другой ошибки, но тогда я исправил все wait-ом. В общем, тут чего-то не хватает
Prostrelov писал(а): ↑13.05.2013 09:46
п.с.
так же не смог найти информации по set -euf
'set' - это встроенная команда shell. Я просто включаю некоторые опции, которые, я считаю, стоит включать для предотвращения последствий возможных ошибок:
-e - это 'errexit'. Завершение скрипта, если какая-то команда завершилась не с 0.
-u - это 'nounset'. Считать переменные без значения (это _не_ то же самое, что пустое значение) ошибкой. Разницу между пустым значением и отсутсвием значения можно увидеть на примере:
Код: Выделить всё
$ ( set -u; echo v=$v )
-bash: v: unbound variable
$ ( set -u; v=''; echo v=$v )
v=
первая команда завершилась ошибкой, вторая - нет.
-f - это 'noglob'. Отключение pathname expansion (подстановка имен файлов вместо * и тд). Иногда, может сработать там, где вы этого совсем не ждете. Поэтому я всегда отключаю, кроме тех случаев, когда точно знаю, зачем мне это нужно.