SSH-Befehl wird nicht beendet

SSH-Befehl wird nicht beendet

Ich habe ein Skript geschrieben, um meine Desktop-Zwischenablage von meinem Android-Telefon aus festzulegen.

#!/bin/sh

ssh -Y user@host "export DISPLAY=:0; echo -n $(termux-clipboard-get) | xclip -selection clipboard"

Das Skript funktioniert wie erwartet, wird aber nicht beendet. Ich muss Ctrl+ drücken C, um zur Eingabeaufforderung zurückzukehren.

Ich habe die -fOption genutzt und sie kehrt sofort zurück. Von man ssh:

-f
Fordert an ssh, kurz vor der Befehlsausführung in den Hintergrund zu gehen. Dies ist nützlich, wenn sshnach Passwörtern oder Passphrasen gefragt wird, der Benutzer dies aber im Hintergrund möchte. […]

Ich bin nicht sicher, ob das die richtige Lösung ist. Es muss nicht im Hintergrund laufen. Es muss nur einen Befehl ausführen und zurückkehren.

Warum kommt meine sshRückkehr nicht? Ist das ssh -fein guter Weg? Gibt es einen besseren Weg?

Antwort1

Ausdiese Antwort:

Auswahlen in X funktionieren durch die Zusammenarbeit zweier X-Clients: Ein X-Client behauptet, er habe eine Auswahl (primär, sekundär, Zwischenablage), und ein anderer X-Client, der die Auswahl einfügen möchte, kontaktiert den ersten Client, um sie zu erhalten.

In Ihrem Fall stirbt das Original xclip, aber sein Kind überlebt, um zu behaupten, dass es die Auswahl hat, und um für zukünftige Clients zu dienen, die einfügen möchten. Es scheint, dass es sich nicht vollständig trennt und der SSH-Server wartet, bis es beendet wird; also wartet Ihr Client, bis es beendet wird. Daher ist + ssherforderlich .CtrlC

Wenn später ein anderer Client behauptet, er habe die Auswahl, xclipwird der Remote-Client beendet und Ihr lokaler Client entsperrt ssh. Das bedeutet, dass Ihr Workaround -fnicht so schlecht ist: Hintergrundprozesse sammeln sich nicht an, es gibt höchstens einen blockierten Client ssh.

Die verlinkte Antwort versucht, ein damit zusammenhängendes Problem zu lösen.Eine andere Antwortdort wird geraten xsel. Tatsächlich blockiert dies in meinen Tests nicht:

ssh -Y user@host "export DISPLAY=:0; echo -n foobar | xsel -i -b"

Der Wechsel xclipzu xselist entscheidend. Ihr ursprünglicher Befehl kann noch weiter verbessert werden.

  • Ich denke, Sie brauchen -Y(oder -X), da die Remote-Befehle nicht mit Ihrem lokalen X-Server interagieren. Es reicht aus, DISPLAYright so einzustellen, xseldass auf die gewünschte Anzeige verwiesen wird.lokalZu xsel.

  • Das ist nicht nötig export. Die Variable ist nur für relevant xsel, daher sollte dieser Codeausschnitt ausreichen:DISPLAY=:0 xsel -i -b

  • Schwerwiegender Fehler. $(termux-clipboard-get)wird lokal erweitert und alles, was Sie erhalten, termux-clipboard-getwird in die Zeichenfolge eingebettet, die Sie an die Remote-Shell übergeben, uminterpretiertals Code.

    Wenn beispielsweise termux-clipboard-getFolgendes zurückgegeben wird ; rm -f /very/important/file; true, wird die Remote-Shell ausgeführt.

    export DISPLAY=:0; echo -n ; rm -f /very/important/file; true | …
    

    Sehen Sie, was es tut? Das Richtige ist, eine Weiterleitung zu senden an ssh:

    termux-clipboard-get | ssh user@host 'DISPLAY=:0 xsel -i -b'
    

    Auf diese Weise wird die Ausgabe termux-clipboard-getniemals als Code behandelt.

  • Ich vermute, Sie haben absichtlich verwendet, echo -num die Ausgabe termux-clipboard-getohne nachfolgende Zeilenumbrüche zu erhalten. Wenn ja, sollten Sie nachfolgende Zeilenumbrüche lokal entfernen undnicht verlassen aufecho:

    printf '%s' "$(termux-clipboard-get)" | …
    

Die endgültige Form kann sein:

printf '%s' "$(termux-clipboard-get)" | ssh user@host 'DISPLAY=:0 xsel -i -b'

Beachten Sie, dass der Befehl nachfolgende Zeilenumbruchzeichen sogar aus Daten entfernt, die als binär interpretiert und nicht verändert werden sollen. NUL-Zeichen sind ebenfalls problematisch. Wenn Sie einige Daten wörtlich übergeben müssen, leiten Sie sie einfach termux-clipboard-getdirekt weiter:

termux-clipboard-get | ssh …

verwandte Informationen