Linux 프로세스가 일부 가비지 문자를 STDOUT으로 보내고 있습니다. 제어 단자가 연결되지 않았습니다.

Linux 프로세스가 일부 가비지 문자를 STDOUT으로 보내고 있습니다. 제어 단자가 연결되지 않았습니다.

kubernetes 포드로 실행되는 컨테이너화된 unimrcp 서버가 있습니다. 컨테이너에 들어가서 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이렇게 하면 다음과 같이 손상된 출력이 표시됩니다.

알 수 없는 명령: filer100000000000000000000000000000000000000000000000000000000000000x0100x0000; FILE//////////////% FILE//////////////% FILE//////////////% FILE//////////////% FILE//////////////% FILE////////////%/%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

프로세스에 제어 터미널이 연결되어 있지 않은 이유는 무엇입니까? 표준 출력에 대한 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

관련 정보