Wie führe ich einen Remote-Befehl aus und übergebe die lokale Datei als Eingabe?


22

Ist es möglich, dies zu tun:

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

Das heißt, ich möchte einen Remote-Befehl mit einer lokalen Datei in einem Schritt ausführen, ohne scpdie Datei zuvor mit zu kopieren.


Es ist möglich, dass auf dem Remotecomputer ein übergeordnetes Verzeichnis der Datei des lokalen Computers im Netzwerk eingebunden ist oder dass Sie die Datei
Uhr

Antworten:


23

Du hast nur ein Symbol verpasst =)

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

Na sicher! Ich frage mich, warum ich keine Eingabeumleitung über ssh in Betracht gezogen habe ?!
Jsj

Was ist, wenn ein Remote-Befehl nur ein Dateiargument annehmen und nicht aus stdin lesen kann?
Iruvar

@ChandraRavoori in diesem Fall müssen Sie es scpvorher mit kopieren .
Ansturm

4
@ChandraRavoori Sie können versuchen, ihm das Argument file /dev/stdinoder zu geben -. Kann oder kann nicht funktionieren ( /dev/stdinist eine Datei, aber die Suche wird fehlschlagen)
Derobert

1
@derobert und rush, haben ein bisschen damit herumgespielt und einen abgedrehten Weg gefunden, dies mithilfe der Prozessersetzung unter bash zu tun. Dies unterliegt immer noch der Suchbeschränkung und kann mit all den zusätzlichen Angeboten, die benötigt werden, unhandlich werden. Beispiel folgt. cat test.file | ssh user @ machine 'bash -c "wc -l <(cat -)"'
iruvar

4

Eine Möglichkeit, die unabhängig vom Befehl funktioniert, besteht darin, die Datei über ein Remote-Dateisystem auf dem Remote-Computer verfügbar zu machen. Da Sie eine SSH-Verbindung haben:

  1. Richten Sie einen umgekehrten SSH-Tunnel ein . Siehe auch SSH kopieren Sie einfach die Datei auf das lokale System
  2. Stellen Sie eine Verzeichnisstruktur Ihres Computers bereit, die die Datei enthält, die auf dem Remotecomputer für SSHFS freigegeben werden soll . ( Beispiel )

Auf diese Weise sind jedoch zusätzliche Bewegungen vor der Befehlsausführung erforderlich.
Ansturm

@Gilles: Ich denke, der Originaltitel war irreführend, und Sie haben seine Frage aufgrund des irreführenden Titels verstanden. Soweit ich das beurteilen kann, wollte er eigentlich nicht auf die lokale Datei einwirken , sondern sie nur als Eingabe übergeben. (Aber Ihre Antwort ist verblüffend, wenn ich sie richtig verstehe. Vielleicht sollte ich die von Ihnen beantwortete Frage stellen, um Ihnen einen Platz zu geben, an dem Sie die Antwort richtig gutschreiben können.) Ich habe den Fragentitel bearbeitet um es mit dem Körper und der gewählten Antwort in Einklang zu bringen.
Iconoclast

@iconoclast Ich erinnere mich nicht an meinen Geisteszustand, als ich das geschrieben habe, aber ich gehe nach dieser Antwort vor. Es erfordert einige Einstellungen, hat jedoch den Vorteil, dass es über die unmittelbaren Anforderungen hinaus auf andere Fälle verallgemeinert werden kann, in denen das Kopieren der Eingabe nicht ausreicht. Ich hätte auch die Umleitung erwähnt, wenn es nicht jemand anderes getan hätte. Die allgemeinere Frage wurde oft in leicht unterschiedlichen Formen gestellt.
Gilles 'SO - hör auf, böse zu sein'

Okay, ich muss deine Antwort falsch verstanden haben. Ich habe es nicht ausprobiert, bin jedoch zu dem Schluss gekommen, dass Sie die Änderung der lokalen Datei durch den Remotecomputer zugelassen haben, seit Sie einen Reverse-Tunnel (vom Remotecomputer zum lokalen Host?) Eingerichtet haben. Ist das nicht der Fall?
Bilderstürmer

@iconoclast Ja, dies ermöglicht dem Remote-Computer, die lokale Datei zu ändern (zusätzlich zum Lesen, was für die Frage erforderlich ist).
Gilles 'SO - hör auf, böse zu sein'

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

Alternativ zur bashProzessersetzung <(cat -)oder < <(xargs -0 -n 1000 cat)(siehe unten) können Sie einfach den Inhalt der angegebenen Dateien verwenden xargsund catweiterleiten wc -l(was portabler ist).

# 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)"'
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.