将命名管道输入重定向到文件
Redirect named pipe input to file
我想创建一个我可以写入的文件,如 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 正确打印行。
问题的答案在评论中。因此,这个问题不应该没有答案。
问题中的代码按预期工作,但是,命名管道所在的路径是一条特殊路径,这就是发送给它的数据永远不会到达脚本的原因。例如Bash中对应的特殊大小写可以在redir.c
.
中找到
问题的解决方案是在该端口上使用真正的 UDP 服务器:
socat -u -v -x udp-listen:8125,fork /dev/null &>/var/log/datadog-agent.log
我想创建一个我可以写入的文件,如 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 正确打印行。
问题的答案在评论中。因此,这个问题不应该没有答案。
问题中的代码按预期工作,但是,命名管道所在的路径是一条特殊路径,这就是发送给它的数据永远不会到达脚本的原因。例如Bash中对应的特殊大小写可以在redir.c
.
问题的解决方案是在该端口上使用真正的 UDP 服务器:
socat -u -v -x udp-listen:8125,fork /dev/null &>/var/log/datadog-agent.log