Come eseguire un comando remoto e passare il file locale come input?


22

È possibile farlo:

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

Vale a dire, voglio eseguire un comando remoto utilizzando un file locale in un solo passaggio, senza prima utilizzare scpper copiare il file.


È possibile se il computer remoto ha un innesto di rete di una directory padre del file del computer locale o se si reindirizza il file nel comando ssh
h3rrmiller,

Risposte:


23

Hai perso solo un simbolo =)

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

Ovviamente! Mi chiedo perché non ho preso in considerazione il reindirizzamento dell'input su ssh ?!
jsj,

Cosa succede se il comando remoto può solo prendere un argomento di file e non leggere da stdin?
Iruvar,

@ChandraRavoori in quel caso devi copiarlo con scpprima.
corsa il

4
@ChandraRavoori Puoi provare a dargli l'argomento file /dev/stdino -. Può o non può funzionare ( /dev/stdinè un file, ma
cercarlo

1
@derobert and rush, ci ha giocato un po 'e ha scoperto un modo bizzarro per farlo usando la sostituzione del processo sotto bash. Questo è ancora soggetto alla limitazione della ricerca e può diventare ingombrante con tutte le citazioni aggiuntive che saranno necessarie. Segue l'esempio. cat test.file | ssh user @ machine 'bash -c "wc -l <(cat -)"'
iruvar,

4

Un modo che funziona indipendentemente dal comando è rendere disponibile il file sul computer remoto tramite un filesystem remoto. Dato che hai una connessione SSH:

  1. Stabilire un tunnel SSH inverso . Vedi anche SSH per copiare facilmente i file sul sistema locale
  2. Montare una struttura di directory della macchina contenente il file da condividere sulla macchina remota con SSHFS . ( Esempio )

Ad ogni modo in questo modo sono necessari ulteriori movimenti prima dell'esecuzione del comando.
corsa il

@Gilles: Penso che il titolo originale fosse fuorviante, e tu hai capito la sua domanda in base al titolo fuorviante. Per quanto posso dire, pensò, in realtà non voleva agire sul file locale, ma semplicemente passarlo come input. (Ma la tua risposta è sorprendente, se la capisco correttamente! Forse dovrei porre la domanda a cui hai risposto, solo per darti un posto dove mettere la risposta dove otterrai il giusto credito per essa.) Ho modificato il titolo delle domande per renderlo coerente con il corpo e con la risposta scelta.
iconoclasta

@iconoclast Non ricordo il mio stato d'animo quando ho scritto questo, ma seguo questa risposta. Richiede un po 'di installazione ma ha il vantaggio di generalizzare oltre il requisito immediato in altri casi in cui non è sufficiente copiare l'input. Avrei anche menzionato il reindirizzamento se qualcun altro non lo avesse fatto. La domanda più generale è stata posta più volte in forme leggermente diverse.
Gilles 'SO- smetti di essere malvagio'

Ok, devo aver frainteso la tua risposta. Non l'ho provato, ma ho dedotto che da quando si stava creando un tunnel inverso (dall'host remoto a quello locale?) Si stava permettendo che il file locale venisse modificato dalla macchina remota. Non è così?
iconoclasta

@iconoclast Sì, questo consente al computer remoto di modificare il file locale (oltre a consentirgli di leggerlo, che è ciò che richiede la domanda).
Gilles 'SO- smetti di essere malvagio'

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

In alternativa al bashprocesso di sostituzione <(cat -)o < <(xargs -0 -n 1000 cat)(vedi sotto) puoi semplicemente usare xargse catreindirizzare il contenuto dei file specificati a wc -l(che è più portabile).

# 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)"'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.