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

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

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

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

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

myapplication.sh | logger        

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

그렇다면 가장 좋고 가장 바람직한 방법은 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내장형 시스템에서는 아무 것도 캡처하지 않습니다.산출에 기록되고 있습니다 /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

관련 정보