TL;DR cat(클라이언트에서)이 비밀번호를 묻는 ssh와 경쟁할 때 실패하는 이 명령줄 템플릿을 수정하는 방법은 무엇입니까?
{ echo some stuff; cat; } | ssh SERVER cat
{ echo some stuff; cat; } | ssh SERVER ls
공개/개인 키 생성에 대해 묻는 것이 아닙니다. 원격 명령이 해당 stdin을 무시할 수 있기 때문에 stdin을 미리 사용하고 싶지 않습니다(이 경우 사용자가 ^D를 입력하도록 강요하는 것은 고통스럽습니다). 원격 명령이 표준 입력을 읽는지 여부를 나타내기 위해 사용자가 템플릿에 옵션을 지정하는 것을 원하지 않습니다. 원격 명령이 표준 입력을 읽는지 여부에 관계없이 템플릿이 작동하기를 원합니다.
세부 정보: SSH를 통해 원격으로 실행되는 명령에 대한 클라이언트 및 서버 측 래퍼를 작성하고 싶습니다. 문제의 명령은 사용자가 선택한 명령이 될 수 있습니다. 래퍼의 목적은 명령 환경을 설정하는 것입니다. 클라이언트 래퍼는 서버 측 래퍼에 소량의 데이터를 보내야 하지만 해당 데이터를 명령줄에서 보내고 싶지 않습니다(표준 입력으로 보내고 싶습니다).
호출하는 방법의 예는 다음과 같습니다.
$ wrapper1 HOST wrapper2 sh -c "cat >file"
This data is sent to the remote side
^D
Wrapper1은 일부 데이터를 계산하여 sh를 실행하기 전에 환경을 설정하는 Wrapper2에 전달합니다. Cat은 표준 입력에서 읽고 원격 측의 파일에 씁니다.
이를 달성하기 위해 클라이언트측 래퍼가 서버측 래퍼로 전송되는 표준 입력 스트림의 시작 부분에 일부 데이터를 삽입하기를 원합니다. 서버 측 래퍼는 실제 명령을 실행하기 전에 stdin에서 추가 데이터를 사용합니다.
주입된 데이터를 보내고 소비한 후 원격 명령의 표준 입력 파이프가 이 데이터 주입이 없는 것과 동일해지기를 원합니다. 원격 명령은 표준 입력에서 아무것도 읽을 수도 있고 읽지 않을 수도 있습니다. 이는 실행 중인 특정 명령에 따라 다릅니다.
어떤 명령이 실행되고 있는지, 그리고 표준 입력에서 읽어야 할 항목이 있는지 미리 알 수 없기 때문에 클라이언트가 원격 명령을 호출하기 전에 전체 표준 입력을 소비하는 것을 원하지 않습니다.
내가하려는 일에 대한 자세한 내용은 다음과 같습니다.
CMD가 미리 알려지지 않은 "ssh HOSTwrapper2CMD" 주위에 Wrapper1을 작성하고 싶습니다(tty가 필요하지 않지만 stdin을 읽을 수도 있고 읽지 않을 수도 있음). Wrapper2가 CMD를 실행하기 전에 Wrapper1은 Wrapper2가 읽을 수 있도록 일부 추가 데이터를 원격 끝에 보냅니다. 나는 래퍼1이 어느 정도 투명해지기를 원합니다. 추가 데이터를 보내고 CMD를 실행하기 전에 추가 데이터를 읽기 위해 원격 명령으로 래퍼2를 실행하는 것을 제외하고는 ssh처럼 작동해야 합니다. 원격 CMD가 stdin을 읽는 경우 "ssh HOST CMD"를 실행하는 것처럼 래퍼1의 stdin 내용을 가져오길 원합니다.
나는 래퍼1이 stdout에 추가 데이터를 기록하는 하위 프로세스를 생성하도록 한 다음 cat을 실행하여 stdin을 stdout에 복사하도록 하여 이 코드를 작성했습니다. Wrapper1은 하위 프로세스의 출력을 ssh 명령의 표준 입력으로 파이프합니다. 그러나 cat과 ssh가 모두 키보드 입력을 위해 경쟁하기 때문에(CMD가 대화형으로 실행되는 경우) ssh에서 비밀번호를 묻는 메시지가 표시되면 이 방법이 실패합니다. 아이의 고양이 앞에 잠을 삽입하면 작동하지만 분명히 최적은 아닙니다.
CMD가 stdin을 읽는지 전혀 모르기 때문에 충돌을 피하기 위해 ssh를 실행하기 전에 모든 stdin을 사용할 수 없습니다. 그럼에도 불구하고 모든 stdin을 읽는 것은 많은 시나리오(예: 매우 크거나 증분 소비가 필요한 경우)에서 차선책입니다.
내가 원하는 것을 할 수 있는 방법이 있나요? 지금 내가 생각할 수 있는 것은 다음 선택 사항을 제공하는 Wrapper1에 대한 옵션뿐입니다.
- 전체 표준 입력을 소비하여 원격 엔드로 보내거나
- /dev/null에서 표준 입력을 리디렉션합니다.
그러나 사용자에게 이 두 가지 옵션 중 하나를 선택하도록 요청하지 않고 일반적으로 래퍼 없이 stdin에서 데이터를 점진적으로 읽을 수 있도록 허용하는 것이 좋습니다.
답변1
따라서 아래와 같이 항상 파일을 STDIN으로 리디렉션하도록 CMD를 설정해 볼 수 있습니다.
cmd < file.txt
아니면 먼저 파일을 읽고 정리한 다음 문자열로 보낼 수도 있습니다.
cmd <<< "string"
그런 다음 CMD 스크립트를 호출할 때 ./wrapper2를 호출하기 전에 매개변수를 있는 그대로 파일에 삽입할 수 있습니다. STDIN이 필요하지 않은 경우 실행 후 임시 파일을 자동으로 삭제하거나 잘라서 잘못된 내용을 전송하지 않도록 하세요.
답변2
질문을 올바르게 이해했는지 확실하지 않습니다.
wrapper1 () {
host="$1"
shift
{
echo "nonsensical statement involving wrapper2"
cat
} | ssh $host wrapper2 "$@"
}
버퍼링에주의를 기울이십시오.