Πώς να ξεφύγουν os.system () κλήσεις;

ψήφοι
98

Όταν χρησιμοποιείτε os.system () είναι συχνά απαραίτητο να ξεφύγουν από τα ονόματα αρχείων και άλλα επιχειρήματα δίνονται σαν παράμετροι σε εντολές. Πως μπορώ να το κάνω? Κατά προτίμηση κάτι που θα μπορούσε να λειτουργήσει σε πολλαπλά λειτουργικά συστήματα / κοχύλια, αλλά κυρίως για το bash.

Είμαι σήμερα κάνει το εξής, αλλά είμαι σίγουρος ότι πρέπει να υπάρχει μια λειτουργία βιβλιοθήκης για αυτό, ή τουλάχιστον ένα πιο καλαίσθητο / εύρωστη / αποδοτική επιλογή:

def sh_escape(s):
   return s.replace((,\\().replace(),\\)).replace( ,\\ )

os.system(cat %s | grep something | sort > %s 
          % (sh_escape(in_filename), 
             sh_escape(out_filename)))

Επεξεργασία: Έχω αποδεχθεί την απλή απάντηση του χρησιμοποιώντας εισαγωγικά, δεν ξέρω γιατί δεν είχα σκεφτεί αυτό? Υποθέτω ότι επειδή ήρθα από τα Windows, όπου και «συμπεριφέρονται λίγο διαφορετικά.

Όσον αφορά την ασφάλεια, καταλαβαίνω την ανησυχία, αλλά, σε αυτή την περίπτωση, είμαι ενδιαφέρονται για μια γρήγορη και εύκολη λύση που os.system () παρέχει, και η πηγή των χορδών είναι είτε δεν δημιουργείται από το χρήστη ή τουλάχιστον εισάγονται από μια έμπιστο χρήστη (μου).

Δημοσιεύθηκε 30/08/2008 στις 10:27
πηγή χρήστη
Σε άλλες γλώσσες...                            


10 απαντήσεις

ψήφοι
3

Πιστεύω ότι os.system ακριβώς επικαλείται ό, τι κέλυφος εντολών έχει ρυθμιστεί για το χρήστη, οπότε δεν νομίζω ότι μπορείτε να το κάνετε σε μια πλατφόρμα ανεξάρτητο τρόπο. εντολή μου shell θα μπορούσε να είναι οτιδήποτε, από bash, emacs, ρουμπίνι, ή ακόμα και Quake3. Μερικά από αυτά τα προγράμματα δεν αναμένουν το είδος των επιχειρημάτων που περνούν σε αυτά και ακόμη και αν έκαναν δεν υπάρχει καμία εγγύηση κάνουν τους διαφεύγει με τον ίδιο τρόπο.

Απαντήθηκε 30/08/2008 στις 10:43
πηγή χρήστη

ψήφοι
69

Αυτό είναι ό, τι μπορώ να χρησιμοποιήσω:

def shellquote(s):
    return "'" + s.replace("'", "'\\''") + "'"

Το κέλυφος θα δέχεται πάντα χρηματιστηριακή όνομα αρχείου και αφαιρέστε τα γύρω εισαγωγικά πριν από τη διοχέτευση στο εν λόγω πρόγραμμα. Αξίζει να σημειωθεί ότι, αυτό αποφεύγει τα προβλήματα με ονόματα που περιέχουν κενά ή οποιοδήποτε άλλο είδος των δυσάρεστων κελύφους μεταχαρακτήρα.

Ενημέρωση : Εάν χρησιμοποιείτε Python 3.3 ή νεότερη έκδοση, χρησιμοποιήστε shlex.quote , αντί να αναπτύσσει τη δική σας.

Απαντήθηκε 30/08/2008 στις 11:13
πηγή χρήστη

ψήφοι
54

Ίσως έχετε ένα συγκεκριμένο λόγο για τη χρήση του os.system(). Αλλά αν δεν θα πρέπει κατά πάσα πιθανότητα να χρησιμοποιούν τη subprocessμονάδα . Μπορείτε να καθορίσετε τους σωλήνες άμεσα και να αποφεύγουν τη χρήση του κελύφους.

Το παρακάτω είναι από PEP324 :

Replacing shell pipe line
-------------------------

output=`dmesg | grep hda`
==>
p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
output = p2.communicate()[0]
Απαντήθηκε 30/08/2008 στις 11:15
πηγή χρήστη

ψήφοι
-2

Εάν χρησιμοποιείτε την εντολή σύστημα, θα ήθελα να προσπαθήσω και λευκή λίστα τι συμβαίνει στην κλήση os.system () .. Για παράδειγμα ..

clean_user_input re.sub("[^a-zA-Z]", "", user_input)
os.system("ls %s" % (clean_user_input))

Η μονάδα υποεπεξεργασία είναι μια καλύτερη επιλογή, και θα ήθελα να συστήσω προσπαθώντας να αποφεύγουν να χρησιμοποιούν κάτι σαν os.system / υπο-όπου αυτό είναι δυνατόν.

Απαντήθηκε 30/08/2008 στις 12:43
πηγή χρήστη

ψήφοι
133

shlex.quote() κάνει ό, τι θέλετε από το python 3.

(Χρησιμοποιήστε pipes.quoteγια την υποστήριξη τόσο python 2 και Python 3)

Απαντήθηκε 11/05/2009 στις 13:06
πηγή χρήστη

ψήφοι
4

Σημειώστε ότι pipes.quote είναι στην πραγματικότητα χωρίζεται σε Python 2.5 και Python 3.1 και δεν είναι ασφαλές στη χρήση - Δεν έχει χειριστεί τα επιχειρήματα μηδενικού μήκους.

>>> from pipes import quote
>>> args = ['arg1', '', 'arg3']
>>> print 'mycommand %s' % (' '.join(quote(arg) for arg in args))
mycommand arg1  arg3

Δείτε Python έκδοσης 7476 ? έχει καθοριστεί σε Python 2.6 και 3.2 και νεότερες.

Απαντήθηκε 11/12/2009 στις 00:03
πηγή χρήστη

ψήφοι
1

Η λειτουργία που χρησιμοποιώ είναι:

def quote_argument(argument):
    return '"%s"' % (
        argument
        .replace('\\', '\\\\')
        .replace('"', '\\"')
        .replace('$', '\\$')
        .replace('`', '\\`')
    )

ότι είναι: Πάντα περικλείουν το επιχείρημα σε διπλά εισαγωγικά, και στη συνέχεια backslash-παραθέσω το μόνο χαρακτήρες ειδικά μέσα σε διπλά εισαγωγικά.

Απαντήθηκε 03/10/2010 στις 22:21
πηγή χρήστη

ψήφοι
8

Ίσως subprocess.list2cmdlineείναι η καλύτερη βολή;

Απαντήθηκε 25/05/2012 στις 08:54
πηγή χρήστη

ψήφοι
-2

Η πραγματική απάντηση είναι: Μην χρησιμοποιείτε os.system()στην πρώτη θέση. Χρησιμοποιήστε subprocess.callαντ 'αυτού και παρέχουν τα χωρίς χαρακτήρα διαφυγής επιχειρήματα.

Απαντήθηκε 25/04/2013 στις 09:44
πηγή χρήστη

ψήφοι
3

Ειδοποίηση : Αυτό είναι μια απάντηση για Python 2.7.x.

Σύμφωνα με την πηγή , pipes.quote()είναι ένας τρόπος για να « Αξιόπιστα παραθέσω μια σειρά ως ένα ενιαίο επιχείρημα για την / bin / sh ». (Αν και είναι ξεπερασμένο από την έκδοση 2.7 και τέλος εκτεθεί δημοσίως στην Python 3.3 ως shelx.quote()συνάρτηση.)

Από την άλλη πλευρά , subprocess.list2cmdline()είναι ένας τρόπος για να « Μετάφραση μια ακολουθία επιχειρημάτων σε μία στοιχειοσειρά γραμμή εντολών, χρησιμοποιώντας τους ίδιους κανόνες με το χρόνο εκτέλεσης MS C ».

Εδώ είμαστε, η ανεξάρτητη πλατφόρμα τρόπο παραθέτοντας χορδές για τις γραμμές εντολών.

import sys
mswindows = (sys.platform == "win32")

if mswindows:
    from subprocess import list2cmdline
    quote_args = list2cmdline
else:
    # POSIX
    from pipes import quote

    def quote_args(seq):
        return ' '.join(quote(arg) for arg in seq)

Χρήση:

# Quote a single argument
print quote_args(['my argument'])

# Quote multiple arguments
my_args = ['This', 'is', 'my arguments']
print quote_args(my_args)
Απαντήθηκε 13/04/2015 στις 03:26
πηγή χρήστη

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more