Ich habe versucht, einige Dateien über SSH zu sichern, aber anstatt tar
die gewünschten zu speichern , habe ich meinen Home-Ordner erhalten. Ich habe einige weitere Tests durchgeführt und es läuft darauf hinaus:
ssh root@server /bin/sh -c "cd /boot && ls -l"
Was zu meiner Überraschung Dateien /root
nicht auflistet /boot
. Aber wenn ich den gesamten /bin/sh
Befehl von einem Terminal aus ausführe, wird er ordnungsgemäß ausgeführt cd
und die /boot
Dateien werden gedruckt .
Was passiert hier?
shell
ssh
cd-command
Ambroz Bizjak
quelle
quelle
ssh root@server /bin/sh -c "ls -l /boot"
?Antworten:
Mit ssh können Sie einen Befehl nicht genau wie bisher als eine Reihe von Argumenten angeben, die an execvp auf dem Remote-Host übergeben werden sollen. Stattdessen werden alle Argumente zu einer Zeichenfolge verkettet und über eine Remote-Shell ausgeführt. Meiner Meinung nach ist dies ein großer Konstruktionsfehler in ssh. In den meisten Fällen handelt es sich um ein gut funktionierendes Unix-Tool. Wenn jedoch ein Befehl angegeben werden soll, wird eine einzelne monolithische Zeichenfolge anstelle von argv verwendet es wurde für MSDOS oder so konzipiert!
Da ssh Ihren Befehl als einzelne Zeichenfolge an weitergibt,
sh -c
müssen Sie keine eigene Zeichenfolge angebensh -c
. Wenn Sie dies tun, ist das Ergebnismit dem ursprünglichen Zitat verloren. Die durch das getrennten Befehle
&&
lauten also:Die erste davon führt eine Shell mit dem Befehlstext "cd" und
$0
= aus"boot"
. Der Befehl "cd" wird erfolgreich ausgeführt, das$0
ist irrelevant und das/bin/sh -c
zeigt Erfolg an, dannls -l
passiert das.quelle
ssh
sich das so verhält, wenn es nicht so wäre, müsste es aufgerufen werdensexec
, nichtssh
.ssh
ist die sichere Version vonrsh
(die sich in dieser Hinsicht gleich verhalten hat) undrlogin
(wirdrsh
aufgerufen,rlogin
wenn keine Befehlszeile übergeben wurde). Es ist nur bedauerlich, dass es nichtrexec
so gut implementiert wird ."`printf "%q " "$@"`"
Mit bash können Sieprintf
eine Zeichenfolge oder Zeichenfolgen mit Shell-Escape-Zeichenfolgen in Anführungszeichen setzen.Es ist ein Zitat Problem. Ssh führt den Befehl, den Sie übergeben, bereits in einer Shell aus. Wenn Sie mehrere Parameter übergeben, werden diese mit einem Leerzeichen dazwischen verkettet, um eine Zeichenfolge zu erstellen. Der Remote-Befehl, den Sie remote ausführen, lautet also
/bin/sh -c cd /boot && ls -l
(keine Anführungszeichen, da die Anführungszeichen in Ihrem Befehl von der lokalen Shell interpretiert wurden)./bin/sh -c cd /boot
läuft/bin/sh
und sagt ihm , den Befehl auszuführencd
und auch Satz$0
zu/boot
. Sobald dies erledigt ist, wird die übergeordnete Shell (die von gestartetesshd
) ausgeführtls -l
.Entfernen Sie in Ihrem Fall einfach das,
sh -c
was völlig nutzlos ist, es sei denn, Ihre Remote-Shell (wie in/etc/passwd
oder einer anderen Kennwortdatenbank angegeben) versteht diesen Befehl nicht.Wenn Sie eine andere Shell aufrufen müssen, müssen Sie den Befehl remote in Anführungszeichen setzen, um ihn vor der Erweiterung durch die von aufgerufene Remote-Shell zu schützen
sshd
. Wenn Ihre Anmeldeshell beispielsweise ein Bindestrich ist und Sie einen bash-Befehl ausführen möchten:quelle
Ich denke, es hat mehr damit zu tun, wie die Optionen von der Shell analysiert werden. Das funktioniert zum Beispiel:
Dies hat das gleiche Problem wie Ihr Befehl:
Wenn Sie den
-v
Schalter auf aktivieren , könnenssh
Sie sehen, was los ist:1. Befehl:
2. Befehl:
In der Regel müssen Sie beim Senden von Befehlen
ssh
die Anführungszeichen und Zeilenumbrüche in Anführungszeichen besonders beachten, da die verschiedenen Ebenen sie entfernen. Auch nicht die Mühe machen, zu senden/bin/sh
.Sie können sehr nützliche Dinge tun, wenn Sie
ssh
die folgenden Zitate verstanden haben . Dadurch wird der Befehl auf dem Remote-Server ausgeführt, die Ergebnisse werden jedoch lokal in einer Datei auf dem System gesammelt, auf dem Sie denssh
Befehl ausgeführt haben:Oder hier, wo Sie ein Verzeichnis auf einem Remote-Server tarieren und es auf dem lokalen System erstellen:
Verweise
quelle
Normalerweise müssen Sie nicht angeben, welche Shell verwendet werden soll. Das funktioniert:
Wenn Ihre Standard-Shell jedoch problematisch ist, müssen Sie lediglich den gesamten Befehl einschließlich des Shell-Aufrufs in Anführungszeichen setzen . Eines der folgenden Werke
quelle
cd /boot && pwd
Arbeit in allen Shells der Hauptfamilien (Bourne, csh, rc)/bin/sh -c "cd /boot && pwd"
nicht funktioniert, wenn die Remote-Shell derrc
Familie angehört, in der"
es keine Besonderheiten gibt.