입력을 필터링하거나 그에 따라 작동한 다음 이를 출력으로 전달하는 명령이 있습니다. 일반적으로 그런 경우라고 생각합니다 stdout
. 그러나 입력을 받아들이고 stdin
아무 작업도 수행하고 아무것도 출력하지 않는 명령도 있습니다.
저는 OS X에 가장 익숙하기 때문에 즉시 떠오르는 두 가지는 다음 pbcopy
과 같습니다 pbpaste
. - 시스템 클립보드에 액세스하는 방법은 다음과 같습니다.
어쨌든, stdout을 얻고 출력을 두 개의 파일로 내보내고 싶다면 stdout
이 명령을 사용할 수 있다는 것을 알고 있습니다 tee
. 나는 그것에 대해 뭔가를 알고 있지만 xargs
그것이 내가 찾고 있는 것이 아니라고 생각합니다.
stdout
두 개 이상의 명령 사이를 전환하기 위해 분할하는 방법을 알고 싶습니다 . 예를 들어:
cat file.txt | stdout-split -c1 pbcopy -c2 grep -i errors
아마도 그것보다 더 좋은 예가 있을 것입니다. 그러나 "음소거"를 피하면서 이를 중계하지 않는 명령에 stdout을 보내는 방법을 알고 싶습니다. 파일과 그 일부를 stdout
보내는 방법을 묻는 것이 아닙니다. 및 클립보드에 복사 - 특정 명령은 그다지 중요하지 않습니다.cat
grep
또한 - 파일로 보내는 방법을 묻는 것이 아닙니다 stdout
. "중복" 질문일 수 있습니다(죄송합니다). 하지만 검색을 좀 해보니 stdout과 파일을 분할하는 방법을 묻는 비슷한 질문만 찾을 수 있었습니다. - 답변 이 질문에는 tee
, 나는 그것이 나에게 효과가 없을 것이라고 생각합니다.
마지막으로 "파이프라인 체인의 마지막 항목으로 pbcopy를 만드는 것이 어떨까요?"라고 물을 수 있습니다. 내 대답은 1) 이를 사용하고 싶지만 콘솔에서 출력을 계속 보려면 어떻게 해야 합니까? 2) 입력을 처리한 후 출력되지 않는 두 개의 명령을 사용하고 싶다면 stdout
어떻게 해야 하나요 ?
tee
아, 한 가지 더 - 명명된 파이프( )를 사용할 수 있다는 것을 알고 있지만 mkfifo
미리 설정할 필요 없이 이 작업을 인라인으로 간결하게 수행할 수 있는 방법이 있기를 바랐습니다. :)
답변1
대체 항목을 사용 tee
하고 처리할 수 있습니다.
cat file.txt | tee >(pbcopy) | grep errors
이렇게 하면 모든 출력이 로 전송되며 cat file.txt
콘솔에서만 pbcopy
결과를 얻을 수 있습니다.grep
tee
이 섹션에는 여러 프로세스를 배치 할 수 있습니다 .
cat file.txt | tee >(pbcopy) >(do_stuff) >(do_more_stuff) | grep errors
답변2
에 여러 파일 이름을 지정할 수 있으며 tee
, 또한 표준 출력을 명령으로 파이프할 수 있습니다. 출력을 여러 명령으로 디스패치하려면 여러 파이프를 만들고 각 파이프를 출력으로 지정해야 합니다 tee
. 이를 수행하는 방법에는 여러 가지가 있습니다.
프로세스 대체
쉘이 ksh93, bash 또는 zsh인 경우 프로세스 대체를 사용할 수 있습니다. 이는 파일 이름을 기대하는 명령에 파이프를 전달하는 방법입니다. 쉘은 파이프를 생성하고 /dev/fd/3
명령처럼 파일 이름을 전달합니다. 번호는파일 설명자파이프가 연결되어 있습니다. 일부 UNIX 변형에서는 지원되지 않습니다 /dev/fd
. 대신 명명된 파이프가 사용됩니다(아래 참조).
tee >(command1) >(command2) | command3
파일 설명자
모든 POSIX 셸에서 여러 가지를 사용할 수 있습니다.파일 설명자분명히. /dev/fd
출력 중 하나를 제외한 모든 항목을 tee
이름으로 지정해야 하므로 이를 위해서는 지원되는 unix 변형이 필요합니다 .
{ { { tee /dev/fd/3 /dev/fd/4 | command1 >&9;
} 3>&1 | command2 >&9;
} 4>&1 | command3 >&9;
} 9>&1
명명된 파이프
가장 기본적이고 이식 가능한 방법은 다음을 사용하는 것입니다.명명된 파이프. 단점은 쓰기 가능한 디렉터리를 찾아 파이프를 만든 다음 정리해야 한다는 것입니다.
tmp_dir=$(mktemp -d)
mkfifo "$tmp_dir/f1" "$tmp_dir/f2"
command1 <"$tmp_dir/f1" & pid1=$!
command2 <"$tmp_dir/f2" & pid2=$!
tee "$tmp_dir/f1" "$tmp_dir/f2" | command3
rm -rf "$tmp_dir"
wait $pid1 $pid2
답변3
프로세스 대체를 가지고 놀아보세요.
mycommand_exec |tee >(grep ook > ook.txt) >(grep eek > eek.txt)
grep
mycommand_exec
출력이 프로세스별 입력과 동일한 두 개의 바이너리입니다.