Blitz8917
Anmeldungsdatum: 8. September 2017
Beiträge: Zähle...
|
Hallo Ubuntu-User, ich bin noch ein neuling auf dem Gebiet Shell Programmierung. Ich habe folgende Frage:
ich habe eine Textdatei wo ich 9 Zeilen stehen habe. Die Zeilen enthalten jeweils einen direkten Pfad zu einem Dokument.
Diese Dateien möchte ich gerne von einem Server per scp auf meinen Rechner kopieren. Dazu soll aus der Datei ausgelesen werden. So das man die Pfade nicht extra eingeben muss. Grüße
Blitz
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11269
Wohnort: München
|
Hallo,
meinst du sowas?
readarray -t server_files < myfiles.txt
scp user@host:{$(printf "%s," "${server_files[@]}")} /path/to/target_dir/
|
Blitz8917
(Themenstarter)
Anmeldungsdatum: 8. September 2017
Beiträge: 2
|
Ich danke dir für die Schnelle Lösung, habe aber schon was anderes funktionierendes gefunden. 😉
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13219
|
Blitz8917 schrieb: Ich danke dir für die Schnelle Lösung, habe aber schon was anderes funktionierendes gefunden. 😉
Dann verrate uns doch, was Du gefunden hast, damit andere auch profitieren können.
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13219
|
seahawk1986 schrieb: Hallo,
meinst du sowas?
readarray -t server_files < myfiles.txt
scp user@host:{$(printf "%s," "${server_files[@]}")} /path/to/target_dir/
Bist Du sicher, dass das funktioniert? | $ server_files=(foo bar)
$ echo scp user@host:{$(printf "%s," "${server_files[@]}")} /path/to/target_dir/
scp user@host:{foo,bar,} /path/to/target_dir/
|
Mir wäre neu, dass scp so eine Konstruktion mit geschweiften Klammern versteht. Vielleicht hattest Du eher etwas mit eval im Sinn um die Brace-Expansion zu nutzen. Aber da würde sich paste eher anbieten, weil man sich dann kein Komma am Ende einfängt. Ich hätte ja eher an so etwas gedacht: | xargs -r -a myfiles.txt -I {} echo scp user@host:{} /path/to/target_dir/
|
Wobei das eklig wird, wenn man immer wieder das Passwort eingeben muss. Dann wäre vielleicht eher so etwas angesagt: | scp $(sed 's#^#user@host:#' myfiles.txt) /path/to/target_dir/
|
|
seahawk1986
Anmeldungsdatum: 27. Oktober 2006
Beiträge: 11269
Wohnort: München
|
rklm schrieb: seahawk1986 schrieb: readarray -t server_files < myfiles.txt
scp user@host:{$(printf "%s," "${server_files[@]}")} /path/to/target_dir/
Bist Du sicher, dass das funktioniert?
Ja (man sollte aber noch einfache Anführungszeichen um die String-Ersetzung bei printf setzen: "'%s'," , damit er nicht über Kommata im Pfad stolpert) - wenn man sich die verbose-Ausgabe von scp anzeigen lässt, sieht man was da passiert:
$ cat myfiles.txt
/tmp/foo1.txt
/tmp/foo2.txt
/tmp/foo3.txt
/tmp/foo4.txt
/tmp/foo,bar.txt
$ readarray -t foo < myfiles.txt
$ scp -v user@host:{$(printf "'%s'," "${foo[@]}")} ./
Executing: program /usr/bin/ssh host host, user user, command scp -v -f {'/tmp/foo1.txt','/tmp/foo2.txt','/tmp/foo3.txt','/tmp/foo4.txt','/tmp/foo,bar.txt',}
OpenSSH_7.5p1, OpenSSL 1.1.0f 25 May 2017
[...]
debug1: Authentication succeeded (password).
Authenticated to host ([192.168.1.173]:22).
debug1: channel 0: new [client-session]
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug1: pledge: network
debug1: client_input_global_request: rtype hostkeys-00@openssh.com want_reply 0
debug1: Sending command: scp -v -f {'/tmp/foo1.txt','/tmp/foo2.txt','/tmp/foo3.txt','/tmp/foo4.txt','/tmp/foo,bar.txt',}
Sending file modes: C0644 2 foo1.txt
Sink: C0644 2 foo1.txt
foo1.txt 100% 2 1.1KB/s 00:00
Sending file modes: C0644 2 foo2.txt
Sink: C0644 2 foo2.txt
foo2.txt 100% 2 1.6KB/s 00:00
Sending file modes: C0644 2 foo3.txt
Sink: C0644 2 foo3.txt
foo3.txt 100% 2 0.0KB/s 00:00
Sending file modes: C0644 2 foo4.txt
Sink: C0644 2 foo4.txt
foo4.txt 100% 2 0.8KB/s 00:00
Sending file modes: C0644 0 foo,bar.txt
Sink: C0644 0 foo,bar.txt
foo,bar.txt 100% 0 0.0KB/s 00:00
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug1: client_input_channel_req: channel 0 rtype eow@openssh.com reply 0
debug1: channel 0: free: client-session, nchannels 1
debug1: fd 0 clearing O_NONBLOCK
debug1: fd 1 clearing O_NONBLOCK
Transferred: sent 2744, received 3372 bytes, in 0.2 seconds
Bytes per second: sent 12636.6, received 15528.6
debug1: Exit status 0
Der Ausdruck für den Pfad wird nach meinem Verständnis erst auf den Server evaluiert (die Shell dort muss das natürlich können), man darf ja z.B. auch Wildcards in den Dateinamen nutzen:
$ scp 'user@host:/tmp/foo*' .
foo,bar.txt 100% 0 0.0KB/s 00:00
foo1.txt 100% 2 0.1KB/s 00:00
foo2.txt 100% 2 1.1KB/s 00:00
foo3.txt 100% 2 0.9KB/s 00:00
foo4.txt 100% 2 1.1KB/s 00:00
|
rklm
Projektleitung
Anmeldungsdatum: 16. Oktober 2011
Beiträge: 13219
|
seahawk1986 schrieb: rklm schrieb:
Bist Du sicher, dass das funktioniert?
Ja (solange es keine Kommata in den Pfaden gibt) - der Pfad wird ja erst auf den Host evaluiert, man kann ja z.B. auch Wildcards in den Dateinamen nutzen.
Ah, cool! Ich würde dann aber trotzdem paste nutzen und die erste Zeile sparen, also: | scp user@host:{$(paste -sd , server_files)} /path/to/target_dir/
|
Wenn man sich die verbose-Ausgabe von scp anzeigen lässt, sieht man was da passiert:
Danke für die Fortbildung! 👍
|
Thomas_Do
Moderator
Anmeldungsdatum: 24. November 2009
Beiträge: 8808
|
Blitz8917 schrieb: Ich danke dir für die Schnelle Lösung, habe aber schon was anderes funktionierendes gefunden. 😉
Ich fände ich es gut, wenn man vor einer Frage hier, erst einmal ausführlich selbst nach einer Lösung suchen würde. Zwischen Frage und Anwort lagen nur 35 min! So schnell ist kein kostenpflichtiger Service 😉. Ist schade, um die "verschwendete" Zeit der Helfer. Ist mir auch schon öfter passiert. In diesem Fall hilft die Antwort aber sicher auch einigen anderen weiter. Danke seahawk1986
|