명령줄에서 작업할 때 일부 입력 스트림에서 지정한 여러 다른 인스턴스에 대해 동일한 작업을 지정한 다음 해당 출력을 특정 방식으로 재결합하려는 경우가 종종 있습니다.
어제의 두 가지 사용 사례:
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
?
우리는 노트북 서버를 Docker 컨테이너로 분리하는 JupyterHub 인스턴스를 실행합니다. 타임스탬프가 표시된 로그를 보고 싶습니다. 하나의 컨테이너로는 충분히 쉽습니다.
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