![Ein Befehl kann nicht über SSH ausgeführt werden](https://rvso.com/image/1711437/Ein%20Befehl%20kann%20nicht%20%C3%BCber%20SSH%20ausgef%C3%BChrt%20werden.png)
Ich führe einen Befehl auf einer FreeBSD-Maschine (xxx.yyy.zzz.net) aus und erhalte die Ausgabe
Befehl
sudo camcontrol devlist | grep -o 'ada[0-9]' | while read -r a ; do sudo camcontrol identify $a | grep rotating ; done
Ausgabe
media RPM non-rotating
media RPM non-rotating
media RPM non-rotating
Ich versuche, den gleichen Befehl mit SSH von einem anderen Computer aus auszuführen
Befehl
ssh xxx.yyy.zzz.net sudo camcontrol devlist | grep -o 'ada[0-9]' | while read -r a ; do sudo camcontrol identify $a | grep rotating ; done
Fehler
sudo: camcontrol: command not found
Antwort1
In Ihrem Befehl |
wird jedes von Ihrer lokalen Shell interpretiert. Das letzte Argument ssh
ist devlist
. ssh
wird lokal aufgerufen (das ist keine Überraschung), aber das gilt auch für alles nach dem ersten |
.
Der Fehler, den Sie erhalten haben, stammt aus sudo
diesem Snippet: do sudo camcontrol identify $a
. Es wird lokal ausgeführt und camcontrol
ist anscheinend auf dem lokalen Computer nicht verfügbar.
Sie benötigen die richtige Escape- oder Anführungszeichen-Einstellung. In diesem Fall möchten Sie vielleicht den gesamten Remote-Befehl in einfache Anführungszeichen setzen:
ssh xxx.yyy.zzz.net 'sudo camcontrol devlist | grep -o "ada[0-9]" | while read -r a ; do sudo camcontrol identify $a | grep rotating ; done'
Beachten Sie, dass ich die einfachen Anführungszeichen geändert habe, die Sie bereits hatten. Die (hinzugefügten) einfachen Anführungszeichen gruppieren nicht nur die gesamte Zeichenfolge, sodass ssh
sie abgerufen wird; sie verhindern auch die lokale Erweiterung von $a
.
Wenn sudo
Sie nach Ihrem Kennwort gefragt werden, wird ein Pseudoterminal benötigt. Sie können die Zuweisung eines Pseudoterminals mit der -t
Option auf erzwingen ssh
(so dass es wie aussieht ssh -t xxx.yyy.zzz.net …
). Beachten Sie, ssh -t
dass auf der Remote-Seite ein Pseudoterminal zugewiesen wird. Remote sudo
fordert zu seinem stderr auf, aber dann werden stdout und stderr von diesem Pseudoterminal „gedruckt“ (wie sie normalerweise auf der Konsole gedruckt werden) und an diesem Punkt können Sie sie nicht mehr auseinanderhalten; der zusammengeführte Stream wird erfasst und auf die lokale Seite übertragen, wo er zu stdout geht. Ohne -t
werden Remote stdout und stderr separat übertragen, gehen Sie zu stdout und stderr auf der lokalen Seite und diese werden schließlich zu dem zusammengeführt (oder auch nicht, wenn umgeleitet) was Sie sehen. Das bedeutet, dass -t
Sie (auf der lokalen Seite) remote stderr nicht von remote stdout unterscheiden können. Wenn Sie die Ausgabe lokal weiter verarbeiten (umleiten) müssen und verwenden, stört -t
jede Eingabeaufforderung von .sudo
Außerdem möchten Sie wahrscheinlich doppelte Anführungszeichen verwenden $a
(sogar in Ihrem ersten Befehl, der kein verwendet ssh
). SieheWarum gerät mein Shell-Skript ins Stocken, wenn es sich um Leerzeichen oder andere Sonderzeichen handelt?