tee를 사용하여 GitHub의 파이프라인 출력을 복제하면 출력이 손실됩니다.

tee를 사용하여 GitHub의 파이프라인 출력을 복제하면 출력이 손실됩니다.

GitHub 저장소 클론의 출력을 파일에 기록해야 한다고 생각했습니다. 내가 달리면

git clone [email protected]:my_repo/my_repo.git | tee -a log

빈 파일을 얻었 log지만 명령줄 출력은 다음과 같습니다.

Cloning into 'my_repo'...
remote: Enumerating objects: 284, done.
remote: Counting objects: 100% (228/228), done.
remote: Compressing objects: 100% (133/133), done.
remote: Total 284 (delta 122), reused 162 (delta 69), pack-reused 56
Receiving objects: 100% (284/284), 873.22 KiB | 2.71 MiB/s, done.
Resolving deltas: 100% (138/138), done.

이것은 나에게 약간의 미스터리가되었습니다. 내 생각에는 파일과 파일을 stderr모두 파이핑해야 할 것 같습니다.stdout

git clone [email protected]:my_repo/my_repo.git 2>&1 | tee -a log

이제 log파일과 명령줄 모두

"my_repo"에 복제...

내가 여기서 무엇을 놓치고 있는 걸까요? 이 remote: ...줄을 파일에 어떻게 넣을 수 있나요 tee?

답변1

주석에서 언급했듯이 gitstdout/error가 터미널인지 확인하십시오. 그렇다면 프로그램은 터미널 출력에 추가 설탕을 추가하여 진행 상황과 일부 통계를 텍스트 형식으로 표시합니다. 그렇지 않은 경우 표준 스트림으로의 출력을 최소한으로 유지합니다.

내부적으로는isatty() 예를 들어 여기에 나와 있습니다.. 이는 명령줄 프로그램의 일반적인 관행입니다. 가장 중요한 것은 ANSI 색상을 제거하는 것입니다. 일반적으로 파일에 색상을 넣거나 파이프 처리를 엉망으로 만들고 싶지 않기 때문입니다. 예를 들어 다음을 확인하세요.

/bin/ls --color=auto -1 # ls print column in pipe
/bin/ls --color=auto | sed -n 'l'
/bin/ls --color=always | sed -n 'l'

항상 억제하거나 항상 인쇄하여 git이를 무시하는 옵션이 있습니다. 진행률 출력이 인쇄되며 (일반적으로) 소비에 사용되지 않습니다. 그럼에도 불구하고:-q--quiet--progressstderr

git clone --progress foo/bar.git 2>&1 | tee log

다른 프로그램에는 유사한 옵션이 없을 수 있으며 데이터를 얻으려면 몇 가지 단계를 거쳐야 합니다. 이는 자동화 스크립트 등을 최소화하기 위해 수행되지만 여전히 인쇄되지만 stderr오류 메시지로 줄어듭니다. 예를 들어 git:

$ git clone -q https://nonexistig-url.com/foo.git
fatal: https://nonexistig-url.com/foo.git/info/refs not valid: 
       is this a git repository?
$ echo $?
128

아무런 진행도 이루어지지 않지만 일반적으로 다음과 같은 경우에 발생하는 오류 메시지가 나타납니다.나중에상상하다. 복제 프로세스 자체의 진행이 억제됩니다.

때로는 후처리나 다른 명령이나 추가 명령 실행 등 다른 방법으로 정보를 얻을 수도 있습니다. 예를 들어 git count-objects -v.


거짓 터미널

출력을 정말로 억제하고 싶고 프로그램에 이와 같은 옵션이 없다면 git, 한 가지 옵션은 프로그램이 터미널에 쓰지 않더라도 "생각"하도록 만드는 것입니다. 이를 달성하기 위한 다양한 방법 중 하나는 임시 항목에 사용하는 방법 중 하나는 어떤 이유로든 해당 항목을 교체하려는 것입니다.체계isatty()항상 true를 반환합니다..

echo 'int isatty(int fd) { return 1; }' | \
gcc -O2 -fpic -shared -ldl -o faketty.so -xc -

strip faketty.so
chmod 400 faketty.so

다음과 같은 래퍼 스크립트와 함께 사용하세요 faketty.

#! /bin/sh -
LD_PRELOAD=/path/to/faketty.so "$@"

다음과 같이 사용됩니다.

faketty git clone foo

코드에서 볼 수 있듯이 실제로는 파일 설명자 검사 등을 수행하지 않으며 단지 해킹일 뿐입니다.


데이터 생성 문제

git clone명령은 출력에 색상을 지정하지 않지만 진행 상황을 표시합니다. 이를 수행하는 방법은 터미널에서 동일한 줄을 반복적으로 덮어쓰는 것입니다. 일반적으로 다음과 같습니다.

Cloning into 'foo'...\n
remote: Enumerating objects: 236, done.        \n
\rReceiving objects:   0% (1/236)   
\rReceiving objects:   1% (3/236)   
\rReceiving objects:   2% (5/236)   
...
\rReceiving objects:  79% (187/236)   
\rremote: Total 236 (delta 0), reused 0 (delta 0), pack-reused 236        \n
...
\rReceiving objects:  99% (234/236)   
\rReceiving objects: 100% (236/236)   
\rReceiving objects: 100% (236/236), 79.45 MiB | 104.73 MiB/s, done.\n
...

여기에서는 \rEnter와 마찬가지로 터미널에 커서를 이동하라고 지시합니다.줄의 시작줄 바꿈/줄 끝 과 달리 \n커서를 줄의 시작 부분으로 이동합니다.다음 줄.

결과는 매번 기록됩니다씌우다remote: Total 236 …이전 줄에서 끝 줄 까지 \n프로세스가 다음 줄에서 계속되면 결과는 뷰어에게 다음과 같이 표시됩니다.

Cloning into 'foo'...
remote: Total 236 (delta 0), reused 0 (delta 0), pack-reused 236        
Receiving objects: 100% (236/236), 79.45 MiB | 104.73 MiB/s, done.
...

각 쓰기에 대한 시각적 진행 상황이 포함됩니다. 이 경우 cat터미널이 캐리지 리턴을 해석할 때 간단한 로그는 괜찮아 보이지만 sed -n l log실제 내용은 표시됩니다. 선택적 유사한 sed 's/\r/\n/g' log디스플레이"철사".

청소하다

에 관해서는이 경우, 있는 그대로 간단한 파이프 또는 로그 슬롯 사후 처리로 sed충분합니다.

sed 's/.*\r//'
# Optionally to trim trailing white space, either of:
sed 's/.*\r//;s/ \+$//'
sed 's/.*\r\| \+$//g'

릴리스, 버전 등에 따라 진행률 출력이 변경될 수 있으므로 다소 취약하므로 정보가 동일하다고 보장되지 않습니다. 출력에 색상이 있는 경우 이러한 시퀀스를 추가로 제거해야 합니다.

표시된 진행률(라이브 카운트)이 손실되고 git명령이 실행되기 전에 파이프로 연결될 때만 최종 결과를 얻습니다.sedtee

관련 정보