직렬 케이블 없이 직렬 콘솔 출력을 로컬 파일에 저장하는 방법

직렬 케이블 없이 직렬 콘솔 출력을 로컬 파일에 저장하는 방법

저는 임베디드 Linux를 실행 중이고 명령줄에 console=/dev/ttyO0,...이 UART에 연결된 터미널 프로그램이 있고 볼 수 있습니다.모든 것시스템에 의해 생성됩니다.

이제 라이브를 실행할 때 이 모든 출력을 파일에 저장하고 싶습니다(미디어가 연결되어 있습니다). 그러나 syslogd, 및 Co.를 사용한 모든 노력은 내가 원하는 결과를 얻지 못했습니다. 일부 메시지는 저장되었지만 일부는 저장되지 않았습니다. 일반적으로 가장 중요한 메시지입니다 klogd.logger

예를 들어, 다음을 실행하면:

myapplication.sh | logger        

echo또한 응용 프로그램의 명령 syslog과 일부 드라이버 메시지가 표시됩니다. print그러나 분할 오류로 인해 애플리케이션이 충돌하는 경우 이 정보는 기록되지 않습니다. 그러나 이것이 가장 귀중한 것입니다!

그렇다면 가장 좋고 가장 원하는 것은 ttyO0파일로 리디렉션하는 것입니다. 그런데 어떻게 해야 할까요?

다음 추천을 찾았습니다.

(stty raw; cat > received.txt) < /dev/ttyO0

그러나 이것은 작동하지 않습니다. 예를 들어 명령을 입력할 수 있지만 ifconfig응답은 파일이나 콘솔에 나타나지 않습니다. 파일이 생성되지 않더라도... :-(

파일과 직렬 콘솔을 모두 가질 수 있다면 좋을 것입니다. 그러나 파일의 우선순위가 더 높습니다.

도와주셔서 감사합니다!

고쳐 쓰다해결책을 찾아서 답변 섹션에 추가했습니다.

답변1

당신은 다소 기본적인 사실을 간과하고 있는 것 같습니다. 파이프라인 가능한 모든 프로그램은 다음 사실에 의존합니다.표준 파일 설명자는 이를 호출하는 프로그램에 관계없이 미리 열린 상태입니다. 파이프와 관련된 대부분의 경우 호출 프로그램은 명령 셸이 됩니다.

세 가지 파일 설명자는 다음과 같습니다.

  • 파일 설명자 #0: 표준 입력 스트림 또는 stdin간단히 설명합니다.
  • 파일 설명자 #1: 표준 출력 스트림 또는 stdout간단히.
  • 파일 설명자 #2: 표준오류 출력스트리밍하거나 stderr간단히.

프로그램이 파일 읽기/쓰기로 파이핑하거나 리디렉션하지 않는 경우 일반적으로 세 개의 파일 설명자 모두 현재 로그인 세션이 실행 중인 TTY 장치를 가리킵니다. 프로그램이 의도적으로 데몬이나 백그라운드/비대화형 프로세스로 시작된 경우 이 모든 것이 파일이나 /dev/null, 또는 일종의 로깅 도구로 전달될 수 있습니다.

오류 메시지는 일반적으로 stderr파이프로 연결된 데이터 출력과 혼합되지 않도록 스트림으로 출력됩니다. 하지만 귀하와 같은 경우에는 캡처하고 싶을 때모두출력의 경우 두 스트림을 모두 가져오도록 시스템에 명시적으로 알려야 합니다.

모든 출력을 파이프로 전달하려면 myapplication.sh다음을 수행해야 할 수 있습니다.

myapplication.sh 2>&1 | logger

"파일 설명자 #2를 #1과 동일한 위치로 리디렉션"이라고 표시된 2>&1다음 두 파일을 동시에 파이프할 수 있습니다.

다음과 같은 작은 스크립트를 사용하여 직접 테스트할 수 있습니다.

#!/bin/sh
echo "this is stdout"
echo "this is stderr" >&2

>&2"이 명령의 표준 출력을 가져와서 표준 오류 스트림으로 보냅니다"를 의미합니다 . 이는 아마도 stderr스크립트에서 출력을 생성하는 가장 쉬운 방법일 것입니다.

이제 이 스크립트를 실행하여 ./test.sh | od -t x1z16진수 덤프 형식의 출력을 얻으면 다음과 같은 결과를 얻게 됩니다.

$ ./test.sh | od -t x1z
this is stderr
0000000 74 68 69 73 20 69 73 20 73 74 64 6f 75 74 0a     >this is stdout.<
0000017

따라서 명령은 stdout출력만 처리합니다 od.

2>&1두 스트림을 병합하기 위해 추가하면 다음과 같은 결과를 얻게 됩니다.

$ ./test.sh 2>&1 | od -t x1z
0000000 74 68 69 73 20 69 73 20 73 74 64 6f 75 74 0a 74  >this is stdout.t<
0000020 68 69 73 20 69 73 20 73 74 64 65 72 72 0a        >his is stderr.<
0000036

이제 두 출력이 모두 파이프로 전송됩니다. 이는 | logger.


두 번째 명령줄은 내장 장치가 터미널에 보내는 것이 아니라 내장 장치가 터미널 프로그램에서 받는 모든 것을 캡처합니다.

(stty raw; cat > received.txt) < /dev/ttyO0

커널 매개변수를 사용하는 임베디드 시스템을 개발 중이라고 말하면 console=/dev/ttyO0본질적으로 /dev/console그래픽 디스플레이(임베디드 장치에는 존재하지 않을 수도 있음)가 아닌 직렬 포트가 될 것입니다.

내장된 장치에서 이 명령을 실행하는 경우 괄호 안의 명령은 다음과 같습니다.표준 입력 스트림(파일 설명자 #0 또는 stdin간단히)가 에 할당됩니다 /dev/ttyO0. 그러나 에 연결된 직렬 회선을 통해 명령을 입력하면 ttyO0기본적으로 이러한 경우가 발생할 수 있으므로 이 입력 리디렉션은 상황을 그대로 다시 적용할 수 있습니다. .

/dev/ttyO0장치는 다른 컴퓨터의 터미널 프로그램에 연결된 UART를 직접 표현한 것입니다. 당신이 그것을 읽으면 당신은 얻을 것이다터미널 프로그램에 입력한 내용만: 이전에 전송된 출력을 다시 읽을 수 없습니다. 여기에 쓰여진 모든 내용은 직렬 케이블 끝에 있는 터미널 프로그램으로 직접 전달됩니다.

직렬 포트의 Unix 명령줄은 일반적으로 다음과 같습니다.원격 에코작동 방식: 터미널 프로그램에 작성한 내용을 보려면 임베디드 시스템의 TTY 드라이버는 사용자가 입력하는 모든 문자의 복사본을 터미널 프로그램으로 다시 보내야 합니다. 이 동작은 비대칭입니다. 터미널 프로그램은 직렬 포트 연결을 통해 수신된 내용의 복사본도 다시 보내지 않습니다.

TTY 드라이버는 Unix 전통에서 많은 일을 요구하기 때문에 복잡한 것입니다. 원격 에코 기능은 그 중 하나일 뿐입니다.

을 사용하면 stty raw효과적으로TTY 드라이버의 일반적으로 유용한 기능을 모두 끄십시오., 원격 에코 기능 포함. 따라서 그 시점부터 명시적으로 읽고 즉시 다시 쓰지 않는 한 /dev/ttyS0터미널 프로그램에 작성된 내용을 볼 수 없습니다 .

stty raw명령이 종료된 후 터미널 프로그램의 모든 입력은 명령으로 들어가고 cat인수 없이 호출되면 변경되지 않은 채 표준 출력으로 전달됩니다. 그러나 표준 출력은 이제 파일로 리디렉션됩니다 received.txt.터미널 프로그램에 입력한 내용만 파일에 기록됩니다.명령이 끝날 때까지 cat- 그리고 파일 끝 문자(보통 Control+D)를 얻을 때만 가능합니다.

received.txt(리디렉션 셸에서 수행할 수 있는 버퍼링으로 인해 파일 끝 문자로 입력을 끝내거나 여러 줄의 텍스트를 입력하지 않는 한 파일에 아무것도 출력되지 않을 수 있습니다 .)

따라서 TTY 드라이버 기능을 끄는 것 외에 (stty raw; cat > received.txt) < /dev/ttyO0임베디드 시스템의 TTY 드라이버는 아무 것도 캡처하지 않습니다.산출쓰기 /dev/ttyO0이 명령은 문제를 해결할 때에만 사용됩니다.직렬 연결: 터미널 프로그램이 보내는 문자를 어떻게든 손상시키는 것으로 의심되는 경우, 이는 터미널 프로그램이 임베디드 장치에 보내는 모든 것을 가장 원시적인 형태로 캡처하는 방법입니다.


녹음하고 싶다면절대적으로 모든 것예를 들어 커널 패닉 메시지를 포함하여 UART 연결에서 이런 일이 발생하는 경우 가장 좋은 방법은 다른 컴퓨터의 터미널 프로그램에 모든 트래픽을 기록하도록 지시하는 것입니다. 많은 터미널 프로그램에는 이 기능이 내장되어 있습니다.

이는 커널에 문제가 발생하면 실제로 더 이상 디스크 파일에 아무 것도 쓸 수 없게 될 수 있기 때문입니다. UART에서 오류 메시지 텍스트를 보내고 이를 수신하는 사람이 이를 발견할 것이라고 신뢰하는 것이 훨씬 간단합니다.

답변2

글쎄요, 답을 찾은 것 같아요. 이렇게 간단하고 필요한 IMHO 문제가 이렇게 "불규칙한" 방식으로 해결되었다는 사실에 매우 놀랐습니다. 하지만 인생도 마찬가지입니다... :-)
어쨌든, telcoM저에게 참조 참조를 주신 분 에게 감사드립니다. 더 많은 참고 자료를 찾아보고 마침내 제가 ttyrpl딱 원하던 가방을 발견했습니다.
패키지 유지 관리는 약 7~10년 전에 중단되었으며 이를 Linux 배포판과 필수 라이브러리에 적용하는 데 시간이 좀 걸렸지만 작동합니다!
그것은 내가 원하는 것을 정확하게 수행합니다. ttyS0/ttyO0의 출력을 수집하여 파일에 저장합니다. 그리고 꼭 필요한 것은 아니지만 멋진 옵션도 많이 있습니다... :-)

답변3

console=/dev/ttyS0 대신 picocom을 사용해 보십시오. 다른 도구도 있지만 picocom이 가장 쉬운 것 같습니다.

이러한 도구 중 하나를 사용하면 출력에 파이프와 티를 사용할 수 있습니다.

picocom /dev/ttyS0 -b 115200 -l | tee my.log

https://askubuntu.com/q/1010232

답변4

노력하다https://tio.github.io- 파일에 대한 로깅을 지원합니다. 예를 들어:

tio /dev/ttyS0 --log --log-file my-log.txt

또는

tio /dev/ttyS0 --log

자동으로 생성된 파일 이름을 사용하여 파일에 직렬 출력을 기록합니다.tio_ttyS0_2022-09-14T08:56:09.log

관련 정보