Linux 进程正在向 STDOUT 发送一些垃圾字符。没有连接控制终端

Linux 进程正在向 STDOUT 发送一些垃圾字符。没有连接控制终端

我有一个容器化的 unimrcp 服务器,它作为 kubernetes pod 运行。当我进入容器并执行ps -ef其输出时,如下所示:

[root@unimrcp-0 fd]# ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0 99 13:13 ?        01:07:38 ./unimrcpserver
root        75     1  0 13:13 ?        00:00:00 [arping] <defunct>
root        76     1  0 13:13 ?        00:00:00 [arping] <defunct>
root       154     0  0 13:14 pts/0    00:00:00 /bin/bash
root       209   154  0 14:21 pts/0    00:00:00 ps -ef

另外,如果我cat /proc/[pid]/fd/1这样做,我会看到一些损坏的输出,如下所示:

未知命令:▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒

为什么进程没有附加控制终端。我已禁用 Unimrcp 记录到标准输出。 CPU 利用率也达到 99%。有人可以帮忙解决这个问题吗?

这是容器的入口点

#!/bin/sh
source /ip-conf.sh; set_control_media_network "UNIMRCP"
CONTROL_IP=$(get_control_ipv4)
MEDIA_IP=$(get_media_ipv4)
LOG_LEVEL=$(echo $LOG_LEVEL | tr -s " " | xargs)
LOG_OUTPUT=$(echo $LOG_OUTPUT | tr -s " " | xargs)
LOG_HEADERS=$(echo $LOG_HEADERS | tr -s " " | xargs)
sed -i 's+<priority>.*</priority>+''<priority>'$LOG_LEVEL'</priority>+g' 
/usr/local/unimrcp/conf/logger.xml
sed -i 's+<output>.*</output>+''<output>'$LOG_OUTPUT'</output>+g' 
/usr/local/unimrcp/conf/logger.xml
sed -i 's+<headers>.*</headers>+''<headers>'$LOG_HEADERS'</headers>+g' 
/usr/local/unimrcp/conf/logger.xml
sed -i 's+<!-- <ip>.*</ip> -->+''<ip>'$CONTROL_IP'</ip>+g' 
/usr/local/unimrcp/conf/unimrcpserver.xml
sed -i 's+<!-- <rtp-ip>.*</rtp-ip> -->+''<rtp-ip>'$MEDIA_IP'</rtp-ip>+g' 
/usr/local/unimrcp/conf/unimrcpserver.xml 
cd /usr/local/unimrcp/bin/
exec ./unimrcpserver

这是 unimrcp 容器内 /proc/1/fd/ 处 ls -l 的输出

total 0
lrwx------ 1 root root 64 Jan  2 12:04 0 -> /dev/null
l-wx------ 1 root root 64 Jan  2 12:04 1 -> pipe:[17601930]
l-wx------ 1 root root 64 Jan  2 12:04 10 -> pipe:[17605635]
lrwx------ 1 root root 64 Jan  2 12:04 11 -> socket:[17605636]
lrwx------ 1 root root 64 Jan  2 12:04 12 -> anon_inode:[eventpoll]
lrwx------ 1 root root 64 Jan  2 12:04 13 -> anon_inode:[eventfd]
lrwx------ 1 root root 64 Jan  2 12:04 14 -> anon_inode:[eventpoll]
lrwx------ 1 root root 64 Jan  2 12:04 15 -> anon_inode:[eventfd]
lrwx------ 1 root root 64 Jan  2 12:04 16 -> anon_inode:[eventpoll]
lrwx------ 1 root root 64 Jan  2 12:04 17 -> socket:[17602110]
lrwx------ 1 root root 64 Jan  2 12:04 18 -> socket:[17602111]
lrwx------ 1 root root 64 Jan  2 12:04 19 -> anon_inode:[eventpoll]
l-wx------ 1 root root 64 Jan  2 12:04 2 -> pipe:[17601931]
lrwx------ 1 root root 64 Jan  2 12:04 20 -> socket:[17603083]
lrwx------ 1 root root 64 Jan  2 12:04 21 -> socket:[17603084]
lr-x------ 1 root root 64 Jan  2 12:04 22 -> /dev/urandom
lrwx------ 1 root root 64 Jan  2 12:04 23 -> socket:[17603087]
lrwx------ 1 root root 64 Jan  2 12:04 24 -> socket:[17603088]
l-wx------ 1 root root 64 Jan  2 12:04 3 -> 
/usr/local/unimrcp/log/unimrcpserver_2020.01.02_12.04.08.988860.log
lrwx------ 1 root root 64 Jan  2 12:04 4 -> anon_inode:[eventpoll]
lr-x------ 1 root root 64 Jan  2 12:04 5 -> pipe:[17605633]
l-wx------ 1 root root 64 Jan  2 12:04 6 -> pipe:[17605633]
lrwx------ 1 root root 64 Jan  2 12:04 7 -> socket:[17605634]
lrwx------ 1 root root 64 Jan  2 12:04 8 -> anon_inode:[eventpoll]
lr-x------ 1 root root 64 Jan  2 12:04 9 -> pipe:[17605635]

答案1

您需要双引号变量扩展。

在命令中

sed -i 's+<headers>.*</headers>+''<headers>'$LOG_HEADERS'</headers>+g' /usr/local/unimrcp/conf/logger.xml

变量扩展$LOG_HEADERS未加引号。这意味着如果变量LOG_HEADERS包含空格,它将被分成多个单词(并且每个单词还将进行文件名通配)。

这意味着如果$LOG_HEADERS是字符串A B C,您将得到命令

sed -i 's+<headers>.*</headers>+''<headers>'A B C'</headers>+g' /usr/local/unimrcp/conf/logger.xml

在此命令中,BC</headers>+g/usr/local/unimrcp/conf/logger.xml将被视为要处理的文件的路径名,并且应用于这些文件的sed表达式包含语法错误。s+<headers>.*</headers>+<headers>A

始终用双引号引用任何变量扩展。在某些情况下,不需要对扩展进行双引号,但记住始终使用双引号会更容易。

你的命令看起来像

sed -i 's+<headers>.*</headers>+''<headers>'"$LOG_HEADERS"'</headers>+g' /usr/local/unimrcp/conf/logger.xml

或者

sed -i "s+<headers>.*</headers>+<headers>$LOG_HEADERS</headers>+g" /usr/local/unimrcp/conf/logger.xml

(事实上​​,只有一个sed命令,因为您可以通过用 分隔每个表达式;或在单独的-e 'expression'参数中给出它们,轻松地将多个编辑串在一起一次调用中)。

当您将它们与 一起使用时,您还需要双引号扩展echo

另请注意,解析 XML 是很多使用 XML 解析器更容易、更健壮。<header>例如,要替换标签的内容,您可以使用

$ cat file.xml
<root>
<header>hello</header>
</root>
$ xmlstarlet ed -u '//header' -v "new data" file.xml
<?xml version="1.0"?>
<root>
  <header>new data</header>
</root>

与引用相关的问题和解答:

除此之外,您的脚本#在第一行缺少初始 - 字符,并且您似乎忽略了是否cd成功更改了工作目录(您真的想/usr/local/unimrcp/bin顺便将工作目录设置为吗?)。

答案2

问题是因为进程没有附加 TTY。 TTY 是进程用来进行交互以输入和输出的设备。由于没有 TTY,Unimrcp 进程使用其 fd 1 (stdout) 进行其线程通信之一(fd 1 附加到进程的管道)。因此,有一些垃圾字符发送到标准输出(不知道到底为什么?)。

将tty附加到进程后,进程fd 1指向/dev/pts/0,这是伪终端。现在我可以以可读格式查看日志。

将这些行添加到 pod yaml 文件中。这解决了问题

containers: - name: unimrcp tty: true stdin: true

相关内容