我有一个容器化的 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
在此命令中,B
、C</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