2016-06-21 11 views
0

Zuerst werde ich das Problem beschreiben. Ich kopiere oft Dateien von meinem Linux-Desktop auf mein Android-Tablet. Aus Gründen, auf die ich lieber nicht eingehen möchte, ist dies am einfachsten, wenn ich sshDroid (einen SSH-Server) auf meinem Tablet ausgeführt und scp von der Shell aus verwendet habe, um Dateien zu kopieren. Der scp Befehl hat die folgende Form:Escaping-Parameter zu Bash-Funktion

scp -P 2222 ./some\ document\:\ with\ subtitle\ -\ author.txt \ 
      [email protected]:/sdcard/uploads 

Das einzige, was in diesem Ausdruck ändert, ist der Name der Datei, und das ist ganz leicht über Tab-Vervollständigung erreicht. Nicht einmal die IP-Adresse ändert sich. Da ich Dateien oft hochlade, möchte ich nicht immer wieder dieselben Zeichen eingeben. Zu diesem Zweck dachte ich, ich würde eine Shell-Funktion schreiben und an .bashrc anhängen. Die Funktion I ist geschrieben wie folgt:

upload(){ scp -P 2222 [email protected] [email protected]:/sdcard/uploads; } 

es Nutzung sein soll:

upload ./some\ document\:\ with\ subtitle\ -\ author.txt 

aber wenn ich es versuche ich erhalten die folgende Ausgabe:

SSHDroid 
Use 'root' as username 
Default password is 'admin' 
[email protected]'s password: 
./some: No such file or directory 
ssh: Could not resolve hostname document: Name or service not known 
with: No such file or directory 
subtitle: No such file or directory 
-: No such file or directory 
author.txt: No such file or directory 

Es sieht aus wie bash entfernt automatisch den Dateinamen, bevor er ihn an die Funktion übergibt, und der Befehl scp behandelt ihn aufgrund der Leerzeichen im Namen als mehrere Dateinamen.

Meine Frage ist: Wie behalte ich die Backslashes in den Parameter, oder wie kann ich es innerhalb der Funktion wiederherstellen? Nachdem ich eine Weile damit herumgespielt habe, bin ich sehr versucht, ein einfaches Python-Skript zu schreiben und es in/usr/local/bin ablegen. Gibt es eine andere bash-native Lösung, die ich vermisse?

+0

Es ist nicht "URL-Kodierung" das ist das Problem, dann ist es String-Splitting. Unescaping passiert immer früh im Parsing-Prozess, aber es soll - das ist ein Feature, kein Bug. Das Problem besteht darin, dass Ihr nicht entesterter Inhalt dann string-split oder glob expandiert wird, weil er nicht korrekt zitiert wurde. Siehe http://mywiki.wooledge.org/BashParser –

+0

BTW, wenn Ihr Ziel ist, ein gutes Verständnis des Ausführungsmodell zu haben [und die BashParser-Seite lässt Sie immer noch weniger als zuversichtlich], berührt BashFAQ # 50 die gleichen Themen, die einige der Missverständnisse hinter dieser Frage zu begründen; siehe http://mywiki.wooledge.org/BashFAQ/050 –

Antwort

2

Zitate!

Nicht aufgeführt, [email protected] verhält sich identisch zu $*; Wenn Sie die ursprüngliche Tokenisierung beibehalten möchten, müssen Sie stattdessen "[email protected]" verwenden. Also:

upload() { scp -P 2222 "[email protected]" [email protected]:/sdcard/uploads; } 
+0

Es funktioniert! Danke für die Antwort und die ausführlichen Links. –