0

I'm trying to copy files in local network with scp. It's working well with filenames without spaces, but it crash with. I've tried to replace " " with "\ " as this exemple, but it don't work. Here is my code:

def connection(locals):
         a = (int(re.search(br'(\d+)%$', locals['child'].after).group(1)))
         print a
         perc = (Decimal(a)/100)
         print (type(perc)), perc
         while gtk.events_pending():
             gtk.main_iteration()
         FileCopy.pbar.set_text("Copy of the file in the Pi...   " + str(a) + "%")
         while gtk.events_pending():
             gtk.main_iteration()
         FileCopy.pbar.set_fraction(perc)

file_pc = "/home/guillaume/folder/a very large name of file with space .smthg"
file_pi = "pi@192.168.X.X:/home/pi/folder/a very large name of file with space .smthg"

if " " in file_pc:
   file_pc = fichier_pc.replace(" ", '\\\ ')   # tried '\\ ' or '\ '
   file_pi = fichier_pi.replace(" ", '\\\ ')   # but no way
else:
   pass
command = "scp %s %s" % tuple(map(pipes.quote, [file_pc, file_pi]))
pexpect.run(command, events={r'\d+%': connection}) # this command is using to get the %

How can I fix this problem ? Thanks

Guillaume
  • 2,752
  • 5
  • 27
  • 42
  • related: [How to escape spaces in path during scp copy in linux?](http://stackoverflow.com/q/19858176/4279) – jfs Mar 29 '14 at 13:12

3 Answers3

3

Use subprocess module and/or shlex.split():

import subprocess
subprocess.call(['scp', file_pc, file_pi])

and you don't need to worry about escaping or quoting anything

m.wasowski
  • 6,329
  • 1
  • 23
  • 30
  • No, I can't. I want to get the output of the command, to display the progressbar. (see [here](http://stackoverflow.com/questions/22687296/python-copy-file-in-local-network-linux-linux-and-output) – Guillaume Mar 29 '14 at 10:06
  • output is displayed on stdout. If you wan't it captured to react in realtime... well, it can be done, but it's a lot of hassle. You need threads, reopening fd descriptor for process stdout with proper flags etc. It would be better to check `paramiko` module, but that's completely different question. – m.wasowski Mar 29 '14 at 10:19
  • I tried paramiko, but, there is a bug with big files (see [here](http://stackoverflow.com/questions/22708942/python-paramiko-module-error-with-callback)). As I say, the script works fine with no spaces in the name. – Guillaume Mar 29 '14 at 12:59
  • @m.wasowski: read [my answer to the question that Guillaume've linked](http://stackoverflow.com/a/22695208/4279). It shows that `scp` prints *nothing* if stdout is a pipe. Though it works with pseudo-tty provided by `pexpect` module (there are no buffering issues in this case). The issue is how to pass filenames with spaces to scp command – jfs Mar 29 '14 at 13:14
  • Ok, I give another solution when i get home – m.wasowski Mar 29 '14 at 13:32
2

You may keep local file file_pc as is (pipes.quote will escape the spaces). The remote file should be changed:

import pipes

file_pi = 'pi@192.168.X.X:/home/pi/folder/file with space.smth'
host, colon, path = file_pi.partition(':')
assert colon
file_pi = host + colon + pipes.quote(path)

i.e., user@host:/path/with space should be changed to user@host:'/path/with space'

jfs
  • 399,953
  • 195
  • 994
  • 1,670
0

You might want to look into fabric, a Python library that streamlines the use of SSH.

from fabric.state import env
from fabric.operations import get

env.user = 'username'
env.key_filename = '/path/to/ssh-key'

get('/remote_path/*', 'local_path/')
rubayeet
  • 9,269
  • 8
  • 46
  • 55
  • `fabric` is implemented on top of [`paramiko` that breaks for large files](http://stackoverflow.com/questions/22708942/python-paramiko-module-error-with-callback) – jfs Mar 29 '14 at 13:49