netcat을 통해 출력에서 ​​dd 데이터를 분리하고 출력을 구문 분석합니다.

netcat을 통해 출력에서 ​​dd 데이터를 분리하고 출력을 구문 분석합니다.

다음 명령을 사용하여 netcat을 통해 dd 출력을 복사했습니다.

$dd if=/dev/zero bs=1024K count=1 | nc <IP_ADDR> <PORT> -q 0
1+0 enregistrements lus
1+0 enregistrements écrits
1048576 bytes (1,0 MB, 1,0 MiB) copied, 0,0590934 s, 17,7 MB/s

그러나 출력을 구문 분석하려고 하면 아무 일도 일어나지 않습니다.

$ dd if=/dev/zero bs=1024K count=1 | nc <IP_ADDR> <PORT> -q 0 | grep copied
1+0 enregistrements lus
1+0 enregistrements écrits
1048576 bytes (1,0 MB, 1,0 MiB) copied, 0,058937 s, 17,8 MB/s

마지막 줄만 인쇄해야 하는데, 출력이 grep으로 전송되지 않는 이유는 무엇입니까? 몇 번이나 리디렉션을 시도했지만 원하는 대로 작동하지 못했습니다.

netcat을 통해 데이터를 보내고 싶지만 나중에 구문 분석하기 위해 출력 메시지(stderr 및 stdin)를 stdout이나 파일로 보내고 싶습니다.

답변1

존재하다

dd if=/dev/zero bs=1024K count=1 | nc <IP_ADDR> <PORT> -q 0 | grep copied

대신 상태 출력이 읽고 있는 .output dd으로 이동하는 것은 불가능합니다 . 해당 출력이 표준 출력에 기록 되면 대신 으로 이동됩니다 .grepgrepncddddncgrep

고맙게도 dd해당 상태 메시지를 표준 출력에 쓰지 않고(그렇지 않으면 <IP_ADDR>우리가 원하지 않는 곳으로 보내질 것입니다) 대신 별도의 스트림인 stderr에 씁니다(이것은 진단 메시지의 일부가 아니라 진단 메시지이기 때문입니다). 정상적인 출력).

(및 의 stdout+stderr은 변경되지 않음)로 연결되는 파이프 에 dd'를 연결 하려면 다음을 수행할 수 있습니다.stderrgrepnc

{ {
  dd if=/dev/zero bs=1M count=1 2>&3 3>&- |
    nc -q 0  <IP_ADDR> <PORT> 3>&-
} 3>&1 >&4 4>&- | grep copied 4>&-; } 4>&1

쉘의 stdin/stdout/stderr이 I, O, E(터미널에서 실행되는 경우 모두 tty 장치를 읽기+쓰기 모드로 엽니다)로 간다고 가정하면 위의 결과는 다음과 같습니다.

cmd \ fd | stdin stdout stderr  3       4
---------+------------------------------------
      dd | I     pipe1  pipe2   closed  closed
      nc | pipe1 O      E       closed  closed
    grep | pipe2 O      E       closed  closed

또는 stderr dd및 stdout+stderr을 nc그대로 사용합니다 grep(그러나 dd의 stdout은 여전히 ​​nc로 이동합니다).

{ 
  dd if=/dev/zero bs=1M count=1 |
    nc -q 0  <IP_ADDR> <PORT>
} 2>&1 | grep copied

각 명령에 대한 fd 할당 테이블은 다음과 같습니다.

cmd \ fd | stdin stdout stderr
---------+--------------------
      dd | I     pipe1  pipe2
      nc | pipe1 pipe2  pipe2
    grep | pipe2 O      E

또 다른 방법이 있습니다:

{ 
  dd if=/dev/zero bs=1M count=1 2>&1 >&3 3>&- |
    grep copied >&2 3>&-
} 3>&1 | nc -q 0  <IP_ADDR> <PORT>

cmd \ fd | stdin stdout stderr  3
---------+-----------------------
      dd | I     pipe1  pipe2
      nc | pipe1 O      E
    grep | pipe2 E      E

하지만 이 출력은 그다지 관련성이 높지 않습니다. 이 1MiB의 데이터는 파이프 버퍼, nc내부 읽기 버퍼 및 소켓 전송 버퍼에 적합할 수 있으므로 실제로 네트워크 처리량을 측정하지 않습니다. dd첫 번째 패킷이 네트워크를 통해 전송되기 전에 반환 될 가능성이 높습니다 ( ncTCP 연결이 활성화되고 표준 입력 읽기를 시작한 직후). iperf반대쪽을 보세요 .

그렇지 않은 경우 iperf다음을 수행하여 전송 처리량을 더 잘 측정할 수 있습니다.

{
  dd bs=1M count=50 2> /dev/null # buffers filled and the TCP connection 
                                 # established and into a steady state
  dd bs=1M count=100 2>&1 >&3 3>&- | grep copied >&2 3>&-
} < /dev/zero 3>&1 | nc -q 0  <IP_ADDR> <PORT>

관련 정보