开发者

Python: split and format space separated values in a string to use in subprocess.check_call

开发者 https://www.devze.com 2023-03-22 13:57 出处:网络
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

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']
0

精彩评论

暂无评论...
验证码 换一张
取 消