I am using subprocess.check_call in combination with rsync.
I need to use arguments for rsync that are coming from a string which contains multiple space separated values, however because the string is a single object it fails in the subprocess.check_call (which expects each argument to be a separate string).
This is what I'm talking about:
import subprocess
rsync_options = '-axh --delete --delete-excluded'
subprocess.check_call(['rsync', rsync_options, '/tmp/1', '/tmp/2'])
This returns the following expection:
subprocess.CalledProcessError: C开发者_JAVA百科ommand '['rsync', '-axh --delete --delete-excluded', '/tmp/1', '/tmp/2']' returned non-zero exit status 1
This works:
subprocess.check_call(['rsync', '-axh', '--delete', '--delete-excluded', '/tmp/1', '/tmp/2'])
How can I generate seperate strings from rsync_options and format them for use in subprocess.check_call also without knowing how many arguments might be provided?
If I understand your question correctly, you can use shlex.split
. (As JAB points out, rsync_options.split()
is also an option in this particular case, but it fails in certain corner cases, as illustrated by the note here.)
>>> import shlex
>>> shlex.split('-axh --delete --delete-excluded')
['-axh', '--delete', '--delete-excluded']
Then you can insert
, append
, or extend
the result in any way you like.
Perhaps the simplest way to construct the final list is concatenation:
>>> rsync_options = '-axh --delete --delete-excluded'
>>> rsync_args = ['rsync'] + shlex.split(rsync_options) + ['/tmp/1', '/tmp/2']
>>> rsync_args
['rsync', '-axh', '--delete', '--delete-excluded', '/tmp/1', '/tmp/2']
But that makes a copy. That probably won't matter in this case, but just for the sake of completeness, here's a way to do it without making a copy:
>>> rsync_args = shlex.split(rsync_options)
>>> rsync_args.extend(['/tmp/1', '/tmp/2'])
>>> rsync_args.insert(0, 'rsync')
>>> rsync_args
['rsync', '-axh', '--delete', '--delete-excluded', '/tmp/1', '/tmp/2']
精彩评论