Nasıl os.system () çağrıları kaçmak için?

oy
98

os.system kullanırken () o dosya adlarını ve komutlara parametre olarak geçirilen diğer argümanlar kaçmak için sık sık gereklidir. Bunu nasıl yapabilirim? bash için birden fazla işletim sistemi / kabukları üzerinde ama özellikle çalışacak Tercihen şey.

Şu anda aşağıdaki yapıyorum ama bunun için bir kütüphane işlevi, ya da en azından daha şık / sağlam / verimli bir seçenek olmalı eminim ediyorum:

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)))

Düzenleme: Bunu düşünmedim neden tırnak kullanmanın basit bir cevap kabul ettik, bilmiyorum; Ben 've biraz farklı bir şekilde davranması nerede Windows'un geldi çünkü sanırım.

Güvenlikle ilgili olarak, bu durumda, ben os.system () sağlayan hızlı ve kolay bir çözüm ilgileniyorum ve dizeleri kaynağı olmayan kullanıcılar tarafından oluşturulan ya da en azından tarafından girilen ya olduğu, endişenizi anlıyorum ama güvenilir kullanıcı (ben).

Oluştur 30/08/2008 saat 08:27
kaynak kullanıcı
Diğer dillerde...                            


10 cevaplar

oy
3

Ben os.system sadece kullanıcı için yapılandırılmış olan komut kabuğu çağırır inanıyoruz, bu yüzden platform bağımsız bir şekilde bunu yapabileceğimi sanmıyorum. Benim komut kabuğu quake3 bile bash, emacs, yakut veya bir şey olabilir. Bu programların bazıları onlara geçiyoruz argümanlar tür beklemiyordum ve bunlar olsa bile onlar kendi aynı şekilde kaçan yapmak garantisi yoktur.

Cevap 30/08/2008 saat 08:43
kaynak kullanıcı

oy
69

Bu benim kullandığım budur:

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

Kabuk her zaman alıntı dosya adı kabul etmek ve söz konusu programa geçirmeden önce çevreleyen tırnak kaldıracaktır. Özellikle, bu boşluk veya kötü kabuk metakarakterinden başka türlü içeren dosya adlarından ile ilgili problemleri önler.

Güncelleme : Python 3.3 veya sonraki ise, kullanmak shlex.quote yerine kendi haddeleme.

Cevap 30/08/2008 saat 09:13
kaynak kullanıcı

oy
54

Belki de kullanmak için özel bir nedeniniz os.system(). Ama değilse muhtemelen kullanarak olmalıdır subprocessmodülü . Doğrudan boruları belirtmek ve kabuk kullanarak önleyebilirsiniz.

Aşağıdaki dan 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]
Cevap 30/08/2008 saat 09:15
kaynak kullanıcı

oy
-2

Eğer sistem komutunu kullanırsanız, ben denemek ve Örneğin os.system () çağrısı .. gider ne beyaz listeye ediyorum ..

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

altişlem modülü daha iyi bir seçenektir ve ben mümkün os.system / alt işlemi gibi bir şey kullanmaktan kaçınmak için çalışıyor öneriyoruz.

Cevap 30/08/2008 saat 10:43
kaynak kullanıcı

oy
133

shlex.quote() Eğer piton 3'ten beri istediğimizi yapar.

(Buna pipes.quotedesteklemek için iki piton 2 ve piton 3)

Cevap 11/05/2009 saat 11:06
kaynak kullanıcı

oy
4

O pipes.quote aslında Python 2.5 ve Python 3.1 kırık ve kullanımı güvenli değildir Not - Sıfır uzunlukta argümanlar işlemez.

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

Bkz Python sorunu 7476 ; Python 2.6 ve 3.2 ve daha yeni olarak giderilmiştir.

Cevap 10/12/2009 saat 22:03
kaynak kullanıcı

oy
1

Kullandığım fonksiyonudur:

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

yani: Hep çift tırnak içine alın argüman ve sonra çift tırnak içine özel tek karakterler tersbölü alıntı.

Cevap 03/10/2010 saat 20:21
kaynak kullanıcı

oy
8

Belki subprocess.list2cmdlinedaha iyi bir atış mı?

Cevap 25/05/2012 saat 06:54
kaynak kullanıcı

oy
-2

Gerçek cevap ise: kullanmayın os.system()ilk etapta. Kullanım subprocess.callyerine ve çıkmamış argümanlar tedarik ediyoruz.

Cevap 25/04/2013 saat 07:44
kaynak kullanıcı

oy
3

Uyarı : Bu Python 2.7.x. için bir cevaptır

Göre kaynağı , pipes.quote()"için bir yoldur Güvenilir için tek argüman olarak bir dize alıntı / bin / sh ". (Her ne kadar sürüm 2.7 yana kaldırıldı ve son olarak Python 3.3 genel olarak maruz shelx.quote()fonksiyonu).

On Öte yandan , subprocess.list2cmdline()"bir yoludur aynı kurallar kullanılarak, bir komut satırı dizesine argümanları dizisi Çevir MS C çalışma zamanı ".

Burada, komut hatları için dizeleri alıntı platform bağımsız bir yoludur.

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)

Kullanımı:

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

# Quote multiple arguments
my_args = ['This', 'is', 'my arguments']
print quote_args(my_args)
Cevap 13/04/2015 saat 02:26
kaynak kullanıcı

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