2

I'm trying to write a script to copy files in my RaspberryPi, from my Desktop PC. Here is my code: (a part)

print "start the copy"   
path_pi = '//192.168.2.2:22/home/pi/Stock/'
file_pc = path_file + "/" + file
print "the file to copy is: ", file_pc

shutil.copy2(file_pc, path_pi + file_pi)

Actually I have this error: (in french)

IOError: [Errno 2] Aucun fichier ou dossier de ce type: '//192.168.2.2:22/home/pi/Stock/exemple.txt'

So, how could I proceed? Must I connect the 2 machines before trying to copy? I have tryed with:

path_pi = r'//192.168.2.2:22/home/pi/Stock'

But the problem is the same. (And file_pc is a variable)

Thanks

Edit: Ok, I found this:

command = 'scp', file_pc, file_pi  
p = subprocess.Popen(command, stdout=subprocess.PIPE) 

But no way to have the output... (work with Shell=False)

1

2 Answers 2

2

shutil.copy2() works with local files. 192.168.2.2:22 suggests that you want to copy files over ssh. You could mount the remote directory (RaspberryPi) onto a local directory on your desktop machine (sshfs) so that shutil.copy2() would work.

If you want to see the output of a command then don't set stdout=PIPE (note: if you set stdout=PIPE then you should read from p.stdout otherwise the process may block forever):

from subprocess import check_call

check_call(['scp', file_pc, file_pi])

scp will print to whatever places your parent Python script prints.

To get the output as a string:

from subprocess import check_output

output = check_output(['scp', file_pc, file_pi])

Though It looks like scp doesn't print anything by default if the output is redirected.

You could use pexpect to make scp think that it runs in a terminal:

import pipes
import re
import pexpect # $ pip install pexpect

def progress(locals):
    # extract percents
    print(int(re.search(br'(\d+)%[^%]*$', locals['child'].after).group(1)))

command = "scp %s %s" % tuple(map(pipes.quote, [file_pc, file_pi]))
status = pexpect.run(command, events={r'\d+%': progress}, withexitstatus=1)[1]
print("Exit status %d" % status)
Sign up to request clarification or add additional context in comments.

9 Comments

Thank you, it's work fine. How can I get the callback in a string?
@Guillaume: I've updated the answer to show how to get subprocess' output
Ok, but: out = check_output(['scp', file_pc, file_pi]) print out Nothing appers, it stay at the first line. In fact, I would like to get the percentage for a progressbar
@Guillaume: update your question or ask a new one specifically about how to get the percentage from scp command.
@Guillaume: I've added pexpect-based solution that can extract progress information from scp
|
2

Do you have SSH enabled? Something like this could help you:

import os
os.system("scp FILE USER@SERVER:PATH")

1 Comment

While this should work, this isn't really a good idea. Using subprocess.call(['scp', filename, '{}@{}:{}'.format(user, hostname, path)]) would be a bit cleaner. os.system is spawning a shell, and evaluating the text, which is both unnecessary and can lead to easy security vulnerabilities if you are putting any user input into that field.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.