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
주석에서 언급했듯이 git
stdout/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
--progress
stderr
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
...
여기에서는 \r
Enter와 마찬가지로 터미널에 커서를 이동하라고 지시합니다.줄의 시작줄 바꿈/줄 끝 과 달리 \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
명령이 실행되기 전에 파이프로 연결될 때만 최종 결과를 얻습니다.sed
tee