ssh targetHost &;fg – funktioniert nicht, aber warum?

ssh targetHost &;fg – funktioniert nicht, aber warum?

Ich habe die folgende Kombination ausprobiert, um die PID der SSH-Sitzung abzurufen (die Ausführung im Hintergrund zeigt die PID an) und dann mit fg zur SSH-Sitzung zurückzukehren und das Passwort einzugeben:

ssh targetHost &; fg

Ich erhalte die folgende Fehlermeldung:

-bash: syntax error near unexpected token `;'

Warum funktioniert das ";" in diesem Fall nicht wie erwartet?

Mein Ziel ist es, eine SSH-Sitzung zu starten und ihre PID zu kennen. Dazu muss ich so wenige Zeilen wie möglich verwenden. Ich muss mehrere SSH-Sitzungen starten, sie in den Hintergrund stellen und sie am Ende beenden – dafür brauche ich die PIDs.

Antwort1

Sie vermischen zwei verschiedene Fälle:

  • foo ; barführt foo aus, wartet, bis es fertig ist, und führt dann bar aus
  • foo & barstartet foo, stellt es in den Hintergrund und startet bar direkt danach.

Du musst dich entscheiden, ob du das eine oder das andere verwendest. Beides geht nicht. ;)

Um Ihr Problem zu lösen, können Sie einfach alle Jobs im Hintergrund ausführen und dann jobzum Auflisten der PIDs verwenden:

michas@lenny:~$ sleep 10 &
[1] 18007
michas@lenny:~$ sleep 10 &
[2] 18011
michas@lenny:~$ sleep 10 &
[3] 18015
michas@lenny:~$ sleep 10 &
[4] 18019
michas@lenny:~$ sleep 10 &
[5] 18026
michas@lenny:~$ jobs -p
18007
18011
18015
18019
18026
michas@lenny:~$ 

Sie müssen die PIDs auch nicht unbedingt zum Senden von Kill-Signalen verwenden. Beispielsweise kill %1wird der erste Hintergrundprozess beendet.

Antwort2

&;ist immer falsch. Wenn Sie Dinge in einem kompakten Einzeiler im Hintergrund ausführen möchten, lassen Sie das ';' ganz weg und verwenden Sie einfach &between commands.

for i in ./*; do my_command "$i" & done

# sehenhttp://mywiki.wooledge.org/BashPitfalls

Antwort3

Andere haben bereits erklärt, warum &;das fehlschlägt. Ich wollte darauf hinweisen, dass die PID des letzten Hintergrundprozesses als gespeichert wird $!. Sie können daher immer auf die PID des letzten Befehls zugreifen:

ssh targetHost & echo $!; fg

Um sie zu beenden, können Sie alle sshSitzungen mit diesem Befehl beenden:

pkill -x ssh

Die xUrsachen pkillund pgrepum dem vollständigen Befehlsnamen zu entsprechen, stellt dies sicher, dass Sie nicht töten sshdoder ssh-agent. Wenn Sie nur Verbindungen zu einem bestimmten Computer töten möchten, können Sie auch Folgendes tun:

pkill $(pgrep -alx ssh | grep TARGET_IP | cut -d ' ' -f 1)

verwandte Informationen