이 파이프라인이 있는 경우:
echo "bar" | nc localhost 6969 < <(echo "foo")
"foo"는 항상 TCP 소켓의 "bar" 앞에 쓰여지나요? 일관된 우선순위가 있습니까?
답변1
존재하다
cmd1 | cmd2
cmd1
그리고 파이프의 쓰기 끝(또는 ksh93의 소켓 쌍)에 연결된 stdout과 파이프의 다른 끝에 연결된 stdin과 cmd2
병렬로 시작합니다 .cmd1
cmd2
존재하다:
cmd < file
cmd
cmd
에 열린 stdin에서 시작 됩니다 file
.
그래서 당신은 볼 수 있습니다
cmd1 | cmd2 < file
충돌; cmd2
stdin이 파이프에서 오는지 cmd1
아니면 file
.
위의 경우 대부분의 쉘에서는 <file
리디렉션이 완료된 후 우선 순위가 부여됩니다.뒤쪽에(쉘은 파이프 사이에 있는 2개의 프로세스를 시작하고,그 다음에각 명령 내의 독립적인 리디렉션을 포함하여 각 명령이 설명됩니다.
이는 cmd2
표준 입력이 file
이고 기록되는 파이프에 echo
판독기가 없음(깨진 파이프)을 의미합니다. 따라서 귀하의 경우에는 결코 성공하지 못할 것이며, bar
다른 프로세스가 파일을 연 후에 글을 쓰면 nc
실행 중인 프로세스가 echo bar
종료될 수도 있습니다 .bar
zsh
그러나 해당 옵션이 켜져 있으면 multios
(기본적으로 켜져 있음) zsh
동일한 파일 설명자(여기서는 0, stdin)를 두 번 리디렉션하려고 시도하고 있음이 감지되고 로 전송된 두 소스의 데이터를 리디렉션하려는 것으로 가정합니다 cmd2
. 그래서 표준 입력 cmd2
으로 보내는 대신 실제로 내부 파이프를 시작합니다.cmd1
file
공급기두 소스에서 데이터를 읽고 이를 다른 파이프를 통해 차례로 전송하는 프로세스입니다 cmd2
.
cmd1 < <(cmd2)
이것은 명명된 파이프(또는 명명된 파이프처럼 동작하는 것)가 cmd1 < file
다른 쪽 끝에서 쓰는 경우 중 하나일 뿐이지 만 그 외에는 크게 다르지 않습니다.file
cmd2
이식 가능한 두 명령의 출력 또는 한 명령의 출력과 파일 내용을 명령으로 보내려면 다음을 사용할 수 있습니다.
{
cmd1
cmd2
} | cmd3
또는:
{
cmd1
cat < file
} | cmd2
그래서 여기 있습니다:
{
echo bar
echo foo
} | nc localhost 6969
답변2
echo
첫 번째 파이프라인 데이터의 리디렉션은 nc
프로세스 교체의 리디렉션으로 덮어쓰여집니다. 즉, nc
프로세스 교체의 입력만 표시됩니다(예: strings ) foo
.
보다 일반적으로,
command1 | command2 <data
command2
읽혀지지 않은 출력입니다 command1
.
두 문자열을 모두 읽으 려면 nc
함께 전달되도록 준비하거나
{ echo "foo"; echo "bar"; } | nc localhost 6969
또는
nc localhost 6969 < <( echo "foo"; echo "bar" )
답변3
어, 왠지 까다로워 보이는군요. C로 뭔가를 작성할 수도 있지만 node.js를 사용하면 이 문제를 해결할 수 있습니다.
#!/usr/bin/env node
'use strict';
const msg = process.argv[2] || process.env.ql_message;
if(!msg){
console.error('quicklock: no message defined in ql_init_message.');
process.exit(1);
}
console.log(msg);
process.stdin.resume().pipe(process.stdout);
명령줄에서 다음과 같이 사용할 수 있습니다.
echo "bar" | initial_message "foo" | nc localhost 6969;
initial_message는 단지 한 가지를 stdout에 기록한 다음 stdin을 stdout에 대한 패스로 보냅니다.
이 경우 "foo"는 항상 "bar" 앞에 쓰여진다고 확실히 가정하겠습니다.