Перенаправить ввод именованного канала в файл - PullRequest
0 голосов
/ 30 октября 2019

Я хотел бы создать файл, в который я могу записать, как описано в документе Датаграмма данных :

echo -n 'a' >/dev/udp/localhost/8125
echo -n 'b' >/dev/udp/localhost/8125
echo -n 'c' >/dev/udp/localhost/8125

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

a
b
c

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

Я создал следующий сценарий:

#!/usr/bin/env bash
set -Eeuo pipefail

log=/var/log/datadog-agent.log
touch $log

# https://docs.datadoghq.com/developers/dogstatsd/datagram_shell/
pipe=/dev/udp/localhost/8125
if [[ ! -p $pipe ]]; then
    rm -f $pipe
    mkdir -p "$(dirname $pipe)"
    mkfifo -m 0666 $pipe
fi
trap 'rm -f $pipe' EXIT

while :; do
    read -r line <$pipe
    echo "$line" >>$log
done

И следующую службу systemd:

[Unit]
Description=Fake Datadog Agent

[Service]
ExecStart=/usr/local/bin/datadog-agent
Type=exec

[Install]
WantedBy=multi-user.target

Служба запускается правильно после выполнения systemctl enable --now datadog-agent, однако, как я уже сказал, в файл журнала ничего не записывается.

Это очень странно для меня, потому что открытиедва экземпляра оболочки, в которых я пишу следующее в первой оболочке:

mkfifo pipe
while :; do read -r line <pipe; echo "$line"; done

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

1 Ответ

0 голосов
/ 14 ноября 2019

Ответ на вопрос можно найти в комментариях к нему. Следовательно, этот вопрос не должен остаться без ответа.

Код из вопроса работает, как и ожидалось, однако путь, в котором находится именованный канал, является особым путем, и именно по этой причине данные, которые отправляются вэто никогда не достигает сценария. Соответствующий специальный корпус в Bash, например, можно найти в redir.c.

. Решение проблемы - использовать настоящий UDP-сервер на этом порту:

socat -u -v -x udp-listen:8125,fork /dev/null &>/var/log/datadog-agent.log
...