예를 들어
# this line should output ssh banner
nc localhost 22
# this line should output the same string expect the replacements
nc localhost 22|sed 's/SSH/XXX/g'
nc localhost 22 > foo # after killing the process, I can see the banner in file `foo`
nc localhost 22|sed 's/SSH/XXX/g' > foo # however I see nothing when sed is used
sed
언급한 대로 파이프 nc
출력을 사용하는 경우 sed
출력을 파일로 리디렉션할 수 없습니다.
또한 결과를 전달하기 위해 다른 명령도 시도했습니다(예 grep
: tr
동일한 결과).
그러나 cat
결과는 파일로 파이프될 수 있습니다. 이상한..
nc localhost 22|cat > foo
그렇다면 왜 이런 일이 발생합니까? cat
이 경우와 다른 명령의 차이점은 무엇입니까? sed
출력을 파일로 어떻게 리디렉션할 수 있나요 cat
?
답변1
$ 고양이 | sed -e 's/foo/bar/' > 출력.txt 부자 ^C $catoutput.txt [아무것도 없습니다]
하지만:
$ 고양이 | sed -e 's/foo/bar/' > 출력.txt 부자 ^D $catoutput.txt 술집
파일에 쓰기(터미널에는 아님)는 일반적으로 C 라이브러리(stdio 함수)에 의해 몇 킬로바이트 단위로 버퍼링됩니다. 파이프를 종료하기 위해 Ctrl-C를 누르면 sed
파이프가 종료되기 전에 버퍼를 쓸 시간이 없으므로 결과 출력 파일은 비어 있게 됩니다. (이것은 종료 신호를 포착하지 못하는 C 라이브러리의 버그라고 말할 수 있지만 실제로는 그렇습니다.)
Plain은 cat
아마도 라인과 같은 복잡한 것을 처리하지 않기 때문에 stdio를 사용하지 않을 것입니다. 그런 부분은 cat -n
다를 수도 있고 아닐 수도 있습니다.
파이프를 종료하기 위해 Ctrl-C를 사용할 필요 없이 파이프 자체가 완료되도록 배열할 수 있습니다. 적어도 내에서는 nc
이 -qN
옵션을 사용하여 다음 후에 종료하도록 지시합니다.질소stdin이 닫힌 후의 시간(초)입니다. 예를 들면 다음과 같습니다.
$ printf '' | nc -q0 localhost 22 | sed 's/SSH/FOO/' > output.txt
$ cat output.txt
FOO-2.0-OpenSSH_7.4p1 Debian-10+deb9u7
또는 버퍼링을 끄는 방법이 최소한 몇 가지 있습니다. 파이프라인에서 버퍼링 끄기그리고 stdout 버퍼를 제거하려면 "unbuffer" 또는 "stdbuf"를 사용하시겠습니까?
GNU sed에는 -u
/ --unbuffered
스위치 도 있습니다
입력 파일에서 최소한의 데이터를 로드하고 출력 버퍼를 더 자주 플러시합니다.