ssh는 묻지 않고 stdin을 읽습니다.

ssh는 묻지 않고 stdin을 읽습니다.

이들은 다르게 작동합니다:

$ seq 1000000 | (ssh localhost sleep 1; wc -l)
675173
$ seq 1000000 | (ssh localhost sleep 1 </dev/null; wc -l)
1000000

stdin 을 읽는 이유는 무엇입니까 ssh?

답변1

-nssh는 옵션(또는 options)을 사용하여 읽지 않도록 지시하지 않는 한 항상 표준 입력을 읽습니다 -f.

그 이유는 다음과 같은 일을 할 수 있기 때문입니다.

tar cf - somedir | ssh otherhost "tar xf -"

ssh는 원격 명령이 입력을 허용하는지 여부를 알 수 없기 때문에 항상 이 작업을 수행합니다.

아마도 첫 번째 명령에서 일어날 수 있는 일은 seq가 네트워크 및 파이프 버퍼(seq -> ssh -> sleep)를 채우고 sleep은 아무것도 읽지 않기 때문에 더 많은 읽기를 기다리면서 차단된 다음 sleep이 종료되어 이러한 문제가 발생한다는 것입니다. 전체 버퍼를 덤프한 다음 seq가 차단 해제되고 나머지는 wc로 전송됩니다.

다음과 유사한 결과를 얻게 됩니다.seq 1000000 | ( cat | cat | sleep 1; wc -l)

두 번째 명령에서는 여전히 stdin을 읽고 있지만 외부적으로 /dev/null을 stdin에 할당했습니다.

답변2

Unix 입/출력은 단방향 통신 기본 요소를 기반으로 합니다. write데이터를 푸시하려면 1을 사용하고, read데이터를 가져오려면 1을 사용하고, 데이터 가용성을 쿼리하려면 1을 사용합니다 select. 데이터 소비자가 "데이터 좀 주세요"라는 요청을 보내고 생산자가 데이터로 응답하거나, 소비자가 "얼마나 많은 데이터를 주실 수 있나요?"라는 요청을 보내는 웹의 일반적인 모델과 다릅니다. "생산자는 크기로 응답합니다. 데이터 소비자는 read사용 가능한 데이터를 검색하기 위해 호출하며 이는 반드시 생산자를 포함할 필요는 없습니다. 예를 들어 파이프에는 버퍼가 있고 버퍼에서 읽는 데 쓰기 끝이 필요하지 않습니다. 데이터 소비자는 데이터가 사용 가능한지 확인하기 위해 호출을 할 수 있으며 select, 이는 생산자와 전혀 관련되지 않습니다.

SSH 서버는 서버에서 실행 중인 애플리케이션이 표준 입력에서 읽기를 적극적으로 시도하는지 여부를 알 수 있습니다. SSH 서버는 select데이터 쓰기가 차단되는지 확인하기 위해 호출할 수 있습니다. 그러나 애플리케이션이 간헐적으로 읽기를 시도하는 경우 SSH 서버가 select정확한 시간에 호출되지 않아 애플리케이션이 데이터를 읽으려고 하는 상황을 놓칠 수 있습니다. 그리고 SSH 서버는 애플리케이션이 표준 입력에서 데이터를 사용할 수 있도록 요청하기 위해 호출을 하는지 여부와 시기를 알 수 있는 방법이 없습니다 select. SSH 서버가 필요할 때 애플리케이션에 데이터를 제공할 수 있는 유일한 방법은 데이터를 사용할 수 있을 때 애플리케이션에 데이터를 제공하는 것입니다.

이를 위해서는 클라이언트가 서버에 데이터를 전송해야 합니다. 따라서 클라이언트는 표준 입력을 읽고 데이터가 사용 가능해지면 즉시 전달합니다.

클라이언트가 표준 입력에서 일부 데이터를 읽고 나면 읽은 내용을 취소할 수 없습니다. 서버 측 애플리케이션이 최종적으로 데이터를 소비하지 않으면 데이터가 손실됩니다.

따라서 호출할 때 sshSSH 연결을 통해 표준 입력을 라우팅할지 여부를 클라이언트 측에서 결정해야 합니다. 이것은 서버가 당신에게 말할 수 있는 것이 아닙니다.

당신은 또한 볼 수 있습니다동일한 셸에서 여러 연결이 시작된 경우 백그라운드에서 실행 중인 SSH 연결이 종료되지 않습니다.터미널과 관련된 유사하지만 더 복잡한 시나리오를 살펴봅니다.

그리고 친구들.

관련 정보