Como executar um comando remoto e passar no arquivo local como entrada?

22

É possível fazer isso:

ssh user@socket command /path/to/file/on/local/machine

Ou seja, eu quero executar um comando remoto usando um arquivo local em uma etapa, sem primeiro usar scppara copiar o arquivo.

jsj
fonte
É possível se o computador remoto montar uma rede de um diretório pai do arquivo da máquina local ou se você redirecionar o arquivo para o comando ssh
h3rrmiller

Respostas:

23

Você perdeu apenas um símbolo =)

ssh user@socket command < /path/to/file/on/local/machine
pressa
fonte
Claro! Eu me pergunto por que não considerei o redirecionamento de entrada pelo ssh ?!
Jsj #
E se o comando remoto puder apenas pegar um argumento de arquivo e não ler no stdin?
Iruvar
@ChandraRavoori, nesse caso, você precisa copiá-lo scpantes.
apressar
4
@ChandraRavoori Você pode tentar dar o argumento de arquivo /dev/stdinou -. Pode ou não trabalho ( /dev/stdiné um arquivo, mas buscando ele irá falhar)
derobert
1
@derobert e rush, brincaram um pouco com ele e descobriram uma maneira hacky de fazê-lo usando a substituição de processos no bash. Isso ainda está sujeito à limitação de busca e pode ficar complicado com todas as citações adicionais que serão necessárias. O exemplo a seguir. cat test.file | ssh user @ machine 'bash -c "wc -l <(cat -)"'
iruvar 26/10/12
4

Uma maneira de funcionar independentemente do comando é disponibilizar o arquivo na máquina remota por meio de um sistema de arquivos remoto. Como você possui uma conexão SSH:

  1. Estabeleça um túnel SSH reverso . Consulte também SSH copia facilmente o arquivo para o sistema local
  2. Monte uma árvore de diretórios da sua máquina contendo o arquivo para compartilhar na máquina remota com o SSHFS . ( Exemplo )
Gilles 'SO- parar de ser mau'
fonte
De qualquer forma, dessa forma, são necessários movimentos adicionais antes da execução do comando.
apressar
@Gilles: Eu acho que o título original era enganoso, e você entendeu a pergunta dele com base no título enganoso. Pelo que sei, ele pensou que ele realmente não queria atuar no arquivo local, mas apenas transmiti-lo como entrada. (Mas sua resposta é incrível, se eu entendi direito! Talvez eu deva fazer a pergunta que você respondeu, apenas para lhe dar um lugar para colocar a resposta onde você receberá os devidos créditos.) Eu editei o título das perguntas para torná-lo consistente com o corpo e com a resposta escolhida.
Iconoclasta
@iconoclast Não me lembro do meu estado de espírito quando escrevi isso, mas segui esta resposta. Requer alguma configuração, mas tem a vantagem de generalizar além do requisito imediato para outros casos em que não é suficiente copiar a entrada. Eu também teria mencionado o redirecionamento se alguém não tivesse feito isso. A pergunta mais geral foi feita muitas vezes de formas ligeiramente diferentes.
Gilles 'SO- stop be evil' em
Ok, devo ter entendido mal a sua resposta. Não tentei, mas deduzi que, desde que você estava estabelecendo um túnel reverso (do host remoto para o local?), Estava permitindo que o arquivo local fosse modificado pela máquina remota. Não é esse o caso?
Iconoclasta
@iconoclast Sim, isso permite que a máquina remota modifique o arquivo local (além de permitir a leitura, que é o que a pergunta requer).
Gilles 'SO- stop be evil' em
1
# What if remote command can only take a file argument and not read from stdin? (1_CR)
ssh user@socket command < /path/to/file/on/local/machine
...
cat test.file | ssh user@machine 'bash -c "wc -l <(cat -)"'  # 1_CR

Como alternativa à bashsubstituição do processo <(cat -)ou < <(xargs -0 -n 1000 cat)(veja abaixo), você pode apenas usar xargse catcanalizar o conteúdo dos arquivos especificados para wc -l(o que é mais portátil).

# Assuming that test.file contains file paths each delimited by an ASCII NUL character \0
# and that we are to count all those lines in all those files (provided by test.file).

#find . -type f -print0 > test.file
# test with repeated line count of ~/.bash_history file
for n in {1..1000}; do printf '%s\000' "${HOME}/.bash_history"; done > test.file

# xargs & cat
ssh localhost 'export LC_ALL=C; xargs -0 -n 1000 cat | wc -l' <test.file

# Bash process substitution
cat test.file | ssh localhost 'bash -c "export LC_ALL=C; wc -l < <(xargs -0 -n 1000 cat)"'
sincero
fonte