명령줄을 사용하여 작업할 때 일부 입력 스트림 사양의 다양한 인스턴스에 대해 동일한 작업을 지정한 다음 특정 방식으로 해당 출력을 재결합하고 싶은 경우가 많습니다.
어제의 두 가지 사용 사례:
PEM 파일에 번들로 포함된 SSL 인증서 묶음의 제목을 보고 싶습니다.
cat mypemfile.crt | (openssl x509 -noout -text | fgrep Subject:)
첫 번째 항목만 표시됩니다. 인증서를 분할하고 각 인증서에 대해 동일한 명령을 실행한 다음 결과를 연결해야 합니다.
csplit
분할할 수 있지만 파일로만 분할할 수 있습니다. 이것은 번거로운 일입니다.왜 말을 못하겠어요
cat mypemfile.crt | csplit-tee '/BEGIN/ .. /END/' | on-each ( openssl x509 -noout -text | fgrep Subject: ) | merge --cat
?
JupyterHub 인스턴스를 실행하고 노트북 서버를 Docker 컨테이너로 분할합니다. 타임스탬프가 표시된 로그를 보고 싶습니다. 컨테이너의 경우 이는 쉽습니다.
sudo docker logs -t -f $container_id
(
-t
타임스탬프를 추가하고-f
파이프를 열어 두세요tail -f
.)타임스탬프별로 정렬하여 모든 컨테이너의 로그를 쉽게 나열할 수 있습니다.
sudo docker ps | awk '{print $1}' | while read container_id do sudo docker logs -t $container_id done | sort
또는
sudo docker ps | awk '{print $1}' | xargs -n1 sudo docker logs -t | sort
또는
sudo docker ps | awk '{print $1}' | parallel sudo docker logs -t {} | sort
-f
그러나 이들 중 어느 것도 로그를 보기 위해 해당 옵션을 사용할 수 없습니다 .왜 그냥 사용할 수 없나요?
sudo docker ps | awk '{print $1}' | csplit-tee /./ | on-each (xargs echo | sudo docker logs -t -f) | merge --line-by-line --lexicographically
또는
sudo docker ps | awk '{print $1}' | parallel --multipipe sudo docker logs -t -f {} | merge --line-by-line --lexicographically
?
분명히 이것은 필요합니다
- 특정 쉘 지원. 어쩌면 고유한 "다중 파이프라인" 기호가 필요할 수도 있습니다.
- 파이프라인 분할 및 병합을 위한 새로운 도구(
csplit-tee
및 )입니다on-each
.merge
- 셸이 병렬 파이프로 처리하도록 도구 내에서 입력 및 출력 파일 설명자를 원하는 수만큼 지정하는 방법에 대한 규칙이 수정되었습니다.
이 작업이 완료되었습니까? 아니면 내 사용 사례에 적용할 수 있는 것과 동등한 것입니까?
특정 커널 지원 없이 이것이 가능합니까? 커널에는 일반적으로 열려 있는 파일 설명자의 최대 개수가 고정되어 있다는 것을 알고 있지만 구현에서는 맹목적으로 모든 파일 설명자를 한 번에 열려고 시도하지 않음으로써 이 문제를 해결할 수 있습니다.
알고보면 가능할까?GNU 병렬가능합니까?
답변1
GNU 병렬 처리 사용:
cat mypemfile.crt |
parallel --pipe -N1 --recstart '-----BEGIN' 'openssl x509 -noout -text | fgrep Subject:'
테스트되지 않음:
sudo docker ps | awk '{print $1}' |
sudo parallel -j0 --lb docker logs -t -f {}
sudo docker ps | awk '{print $1}' |
sudo parallel -j0 --tag --lb docker logs -t -f {}
답변2
아니요, 쉘은 그렇게 할 수 없습니다. 파이프는 일반적으로 다른 프로세스에서 소스에서 대상으로의 단순한 스트림입니다.
첫 번째 예를 살펴보겠습니다.
cat mypemfile.crt |
(openssl x509 -noout -text | fgrep Subject:)
BEGIN 및 END가 포함된 라인을 따라 입력 파일을 분할하기를 원하지만 cat
내용은 신경 쓰지 않고 파이프에는 레코드 구분 기호의 범위를 벗어난 표시가 없습니다.
파이프라인 소스와 대상의 특정 규칙을 통해 이를 달성할 수 있지만 이렇게 하면 작성자가 의도하지 않은 작업을 수행하기 위해 프로그램을 빌딩 블록으로 결합하는 기능인 파이프라인의 주요 이점이 제거됩니다.
openssl
이 특정 예에서는 openssl
여러 스트림을 처리하도록 수정하고 해당 여러 스트림을 제공하도록 수정하는 것보다 하나의 스트림에서 여러 인증서를 처리하도록 수정하는 cat
것이 훨씬 쉽습니다 .