38

I need to run an rsync command from Python. Is this possible and if so, how do I do it?

rsync -Ccavz --delete DJStatic username@website
Steve Lorimer
  • 27,059
  • 17
  • 118
  • 213
Marcus
  • 9,032
  • 11
  • 45
  • 84
  • 3
    you can run shell commands from python http://docs.python.org/2/library/subprocess.html, also `fabric` provides a nice api that wraps many comman shell commands http://docs.fabfile.org/en/1.4.0/index.html – dm03514 Aug 21 '13 at 23:14
  • 2
    In 2017 there is now a pure-python rsync library :: [pyrsync](https://github.com/isislovecruft/pyrsync) (not a wrapper) – philshem Feb 17 '17 at 22:08
  • 1
    @philshem: It seems that repo hasn't been updated since 2013. What advantage does it offer vs. the system call? – Bryan P Apr 13 '21 at 23:07
  • I have written a very basic wrapper using system's rsync and pythons subprocess, providing some features like printing the progress etc for my own personal purposes: https://github.com/lfreist/PyRsync... – prog2de Jan 10 '22 at 22:08

1 Answers1

31

You can call a subprocess from python using the following snippet

import subprocess
subprocess.call(["ls", "-l"])

In your case, it would be something like this

subprocess.call(["rsync", "-Ccavz", "--delete","DJStatic", "username@website"])

See here for more details.

philshem
  • 24,761
  • 8
  • 61
  • 127
  • 8
    `subprocess.call("rsync -Ccavz --delete DJStatic username@website".split())` is slightly more readable and practical to type. – jolvi Jun 09 '17 at 14:51
  • 15
    @jolvi if none of your arguments have spaces ... – blueFast Feb 18 '19 at 08:23
  • 6
    Use `shlex.split(s)` instead of regular `s.split()` to split arguments up as a normal (POSIX) shell would. – Chris L. Barnes Mar 27 '20 at 17:02
  • 2
    @jolvi's version (passing command as string) should not be used! Pass the arguments as a list of strings. It will save you tons of time debugging later on when you can't figure out why your shell command isn't doing what you expect due to some quotes or spaces in a variable somewhere. The tradeoff of saving 2-3 seconds of typing just isn't worth it – Brandon Oct 09 '20 at 19:17
  • @Brandon: For those who don't have spaces in the command, that's totally fine, and it is easier. If there are spaces, that approach can be fixed using `shlex.split()` instead of `split()`, as mentioned by Chris L. Barnes. I think it's fine to use that solution if you do so cautiously. Unless...is there some other specific issue this causes? – jvriesem Aug 20 '21 at 20:39
  • @jvriesem you are 100% correct, using `shlex.split` solves the problem, as long as you ensure you always use it when passing a command as a string – Brandon Aug 27 '21 at 16:43