【发布时间】:2019-10-30 12:27:02
【问题描述】:
我想创建一个可以写入的文件,如Datadog Datagram docs 中所述:
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 后正确启动,但是,正如我所说,没有任何内容被写入日志文件。
这对我来说很奇怪,因为打开了两个 shell 实例,我在第一个 shell 中编写了以下内容:
mkfifo pipe
while :; do read -r line <pipe; echo "$line"; done
然后在第二个 shell 中开始发送数据正确打印行。
【问题讨论】:
-
mkfifo -m 0666 /dev/udp/localhost/8125- 你认为这里会发生什么?/dev/udp/*不是文件,不是fifo,它是经过特殊处理的特殊文件。如果您在/dev/udp创建自己的fifo,则不再处理它,您只是在写入fifo。 -
@KamilCuk 我认为内核不知道 /dev/udp 和 /dev/tcp。我相信这些是只有 shell 才能识别的特殊字符串。 bash 处理 /dev/udp 和 /dev/tcp 并尝试创建套接字。
-
这个 datadog 程序从 udp 套接字 读取,而不是管道或文件。
-
我想将回显到该特定路径的任何内容捕获到插入换行符的文件中。
-
查看 bash 源代码,我相信您将不得不 patch bash to do that。无论如何,看起来都像 bash redirects 路径。在不改变写作方面的情况下,我认为您无能为力,
echo 123 | tee /dev/udp/localhost/8125之类的东西可能会起作用。
标签: bash shell named-pipes