TL; DR Como posso consertar este modelo de linha de comando, que falha quando o gato (no lado do cliente) enfrenta o ssh solicitando uma senha?
{ echo some stuff; cat; } | ssh SERVER cat
{ echo some stuff; cat; } | ssh SERVER ls
Não estou perguntando sobre como criar chaves públicas / privadas. Eu não quero consumir stdin antecipadamente, uma vez que o comando remoto pode ser algo que ignora seu stdin (nesse caso, forçar o usuário a digitar ^ D é uma dor). Não quero que o usuário tenha que especificar uma opção para o modelo para indicar se o comando remoto lerá ou não seu stdin. Eu quero que o modelo funcione independentemente de o comando remoto ler ou não seu stdin.
Detalhes: Eu quero escrever wrappers do lado do cliente e do servidor para um comando ser executado remotamente via ssh. O comando em questão pode ser qualquer comando da escolha do usuário. O objetivo dos wrappers é configurar o ambiente do comando. O wrapper do lado do cliente precisa enviar uma pequena quantidade de dados para o wrapper do lado do servidor, mas eu não quero enviar esses dados na linha de comando (eu quero enviá-lo no stdin).
Veja um exemplo de como isso pode ser chamado:
$ wrapper1 HOST wrapper2 sh -c "cat >file"
This data is sent to the remote side
^D
O Wrapper1 calcula alguns dados, passa para o wrapper2, que configura o ambiente antes de executar sh. Gato lê stdin e escreve em arquivo no lado remoto.
Para isso, desejo que o wrapper do lado do cliente injete alguns dados no início do fluxo de stdin que é enviado para o wrapper do lado do servidor. Esses dados extras serão consumidos do stdin pelo wrapper do lado do servidor antes que o comando real seja executado.
Após os dados injetados terem sido enviados e consumidos, eu quero que o pipeline stdin para o comando remoto seja o mesmo que teria sido sem essa injeção de dados. O comando remoto pode ou não se incomodar em ler qualquer coisa de seu stdin - isso depende do comando específico que está sendo executado.
Como o comando que está sendo executado não é conhecido de antemão, e não é conhecido de antemão se ele precisa ler qualquer coisa de stdin, eu não quero que o lado do cliente consuma seu stdin inteiro antes de chamar o comando remoto. / p>
Aqui estão mais detalhes do que estou tentando fazer:
Eu quero escrever wrapper1 em torno de "ssh HOST wrapper2 CMD", onde o CMD não é conhecido antecipadamente (suponha que não exija um tty, mas pode ou não ler stdin). O wrapper1 enviará alguns dados extras para o lado remoto para serem lidos pelo wrapper2 antes do wrapper2 execs CMD. Eu quero wrapper1 para ser mais ou menos transparente; ele deve funcionar da mesma forma que o ssh funciona, exceto para enviar os dados extras e executar o wrapper2 como o comando remoto para ler os dados extras antes de executar o CMD. Se o CMD remoto ler stdin, quero que ele obtenha o conteúdo do stdin do wrapper1, como se "ssh HOST CMD" fosse executado.
Eu codifiquei isso tendo o wrapper1 criando um processo filho que grava os dados extras no stdout, seguido pelo execing cat para copiar o stdin para stdout. Wrapper1 canaliza a saída do processo filho para o stdin do comando ssh. No entanto, essa abordagem falha quando o ssh solicita uma senha, pois tanto o cat quanto o ssh estão disputando a entrada do teclado (quando o CMD está sendo executado de forma interativa). Se eu inserir um sono antes do gato da criança, ele funcionará, mas obviamente isso não é o ideal.
Como não sei se o CMD lê stdin, não consigo consumir todos os stdin antes de executar o ssh para evitar o conflito. Em qualquer caso, é suboptimal para ler todos os stdin em muitos cenários (como quando é muito grande, ou precisa ser consumido de forma incremental).
Existe alguma maneira de fazer o que eu quero? Agora tudo o que posso pensar é uma opção para wrapper1 que dá a escolha de:
- Consumir todo o seu stdin e enviá-lo para o lado remoto ou
- Redirecionar stdin de / dev / null.
Mas, seria melhor evitar que o usuário escolha uma das duas opções e permitir que os dados de stdin sejam lidos de forma incremental, como normalmente seria sem os wrappers.