मैं rsync के साथ संयोजन में subprocess.check_call का उपयोग कर रहा हूं।

मुझे rsync के लिए तर्कों का उपयोग करने की आवश्यकता है जो एक स्ट्रिंग से आ रहे हैं जिसमें कई स्थान अलग किए गए मान हैं, हालांकि स्ट्रिंग एक एकल वस्तु है क्योंकि यह subprocess.check_call (जो प्रत्येक तर्क को एक अलग स्ट्रिंग होने की अपेक्षा करता है) में विफल रहता है।

मैं इसी बारे में बात कर रहा हूं:

import subprocess
rsync_options = '-axh --delete --delete-excluded'
subprocess.check_call(['rsync', rsync_options, '/tmp/1', '/tmp/2'])

यह निम्नलिखित अपेक्षा देता है:

subprocess.CalledProcessError: Command '['rsync', '-axh --delete --delete-excluded', '/tmp/1', '/tmp/2']' returned non-zero exit status 1

यह काम:

subprocess.check_call(['rsync', '-axh', '--delete', '--delete-excluded', '/tmp/1', '/tmp/2'])

मैं rsync_options से अलग स्ट्रिंग कैसे उत्पन्न कर सकता हूं और उन्हें subprocess.check_call में उपयोग के लिए प्रारूपित कर सकता हूं, यह जाने बिना कि कितने तर्क प्रदान किए जा सकते हैं?

2
jelloir 25 जुलाई 2011, 17:17

1 उत्तर

सबसे बढ़िया उत्तर

अगर मैं आपके प्रश्न को सही ढंग से समझता हूं, तो आप shlex.split का उपयोग कर सकते हैं। . (जैसा कि जेएबी बताता है, इस विशेष मामले में rsync_options.split() भी एक विकल्प है, लेकिन यह कुछ कोने के मामलों में विफल रहता है, जैसा कि यहां नोट में दिखाया गया है।)

>>> import shlex
>>> shlex.split('-axh --delete --delete-excluded')
['-axh', '--delete', '--delete-excluded']

फिर आप किसी भी तरह से परिणाम insert, append, या extend कर सकते हैं।


शायद अंतिम सूची बनाने का सबसे आसान तरीका संयोजन है:

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

लेकिन यह एक प्रतिलिपि बनाता है। यह शायद इस मामले में कोई मायने नहीं रखेगा, लेकिन केवल पूर्णता के लिए, यहां एक प्रतिलिपि बनाए बिना इसे करने का एक तरीका है:

>>> 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']
3
senderle 25 जुलाई 2011, 18:33
1
इस स्थिति में str.split() ठीक काम कर सकता है, और संभावित रूप से अधिक कुशल हो सकता है। '-axh --delete --delete-excluded'.split() -> ['-axh', '--delete', '--delete-excluded']
 – 
JAB
25 जुलाई 2011, 17:35
स्प्लिट निश्चित रूप से इस विशेष उदाहरण के लिए काम करता है। लेकिन ओपी ने एक ऐसा उत्तर मांगा जो "यह जाने बिना कि कितने तर्क दिए जा सकते हैं" काम करता है। मैं मान रहा हूं कि इसका अर्थ "उन तर्कों के प्रारूप को जाने बिना" भी है।
 – 
senderle
25 जुलाई 2011, 17:36
@senderle, मैंने टाइपो अपडेट किया है - हाँ यह एक सूची होनी चाहिए।
 – 
jelloir
25 जुलाई 2011, 18:16
विभाजन और shlex.split का उपयोग करना काम नहीं करता क्योंकि subprocess.check_call स्ट्रिंग्स की अपेक्षा करता है और यह एक सूची तैयार करता है। rsync_command = [] rsync_command = ['rsync', shlex.split(rsync_options), '/tmp/1', '/tmp/2'] subprocess.check_call(rsync_command) TypeError: execv() arg 2 must contain only strings
 – 
jelloir
25 जुलाई 2011, 18:22
इसलिए "आप किसी भी तरह से परिणाम insert, append, या extend कर सकते हैं।" लेकिन मैंने इसे और अधिक स्पष्ट होने के लिए संपादित किया है।
 – 
senderle
25 जुलाई 2011, 18:29