Soru Python'da çift alıntı kabuk komutlarını alt işlemlere geçirme.Popen ()?


Kabuğun içinde çalışan bir komutun sadece etrafındaki komut satırında yalnızca çift tırnaklı tırnaklarla çalışan bir komut iletmeye çalışıyorum. "concat:file1|file2" ffmpeg için argüman.

Ancak bu işi python ile yapamam subprocess.Popen(). Herkes bir altprocess.Popen içine nasıl geçtiğini bir fikrim var mı?

İşte kod:

command = "ffmpeg -i "concat:1.ts|2.ts" -vcodec copy -acodec copy temp.mp4"

output,error = subprocess.Popen(command, universal_newlines=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE).communicate()

Bunu yaptığımda, ffmpeg, concat segementi etrafında alıntı yapmaktan başka bir yol almayacaktır. Bu satırı başarıyla altprocess.Popen komutuna iletmenin bir yolu var mı?


34
2018-02-18 03:03


Menşei


Komut çalışmanızın etrafında 'tek tırnak' kullanmıyor musunuz? Eğer terminalde yazdığınız komutu tam olarak yazdığınız gibi giriyorsanız, bu teklifleri işleyen kabuk olacaktır, ffmpeg değil! - wim


Cevaplar:


Belirtilen dize sürümü yerine çağrı listesi formunu kullanmanızı öneririm:

command = ["ffmpeg", "-i", "concat:1.ts|2.ts", "-vcodec", "copy",
           "-acodec", "copy", "temp.mp4"]
output,error  = subprocess.Popen(
                    command, universal_newlines=True,
                    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()

Bu, son işlemden geçirilecek olan kesin parametre kümesini daha doğru bir şekilde temsil eder ve kabuk alıntılama ile uğraşma ihtiyacını ortadan kaldırır.

Yani, düz dize sürümünü kesinlikle kullanmak isterseniz, sadece farklı tırnak kullanın (ve shell=True):

command = 'ffmpeg -i "concat:1.ts|2.ts" -vcodec copy -acodec copy temp.mp4'
output,error  = subprocess.Popen(
                    command, universal_newlines=True, shell=True,
                    stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()

31
2018-02-18 03:10



Ve Unix'te (en azından), kullanmanız gerekir shell=True eğer bir dizgeyi geçecekseniz. Aksi halde, anladığım kadarıyla, python adında bir program arayacak ffmpeg -i "concat.... senin yolunda - hangi olmaz. - mgilson
cevap vermek için zaman ayırdığınız için teşekkürler, gerçek ffmpeg komutu, literal alıntılar, concit etrafında geçirir: file1 | file2 argümanı, bu yüzden python subprocess.Popen komutundan ffmpeg'e yapılan literal teklifleri iletmenin bir yolunu arıyorum - Fight Fire With Fire
@FightFireWithFire Son sürümü sizin için çalışmıyor mu? İstediğini yaptığına inanıyorum. - Matt
İlk versiyonda '' concat: 1.ts | 2.ts '' kullanın - tdelaney
@FightFireWithFire: Eğer iki türden alıntıya ihtiyacınız varsa, o zaman bir üçlü-tırnak Python literal kullanabilirsiniz: cmd = r "" "cmd" concat: 1.ts | 2.ts "$ '\ t' ..." " " - jfs


Bu python ile çalışır 2.7.3 Stttr'ı stdout'a aktarma komutu python'un eski sürümlerinden beri değişmiştir:

Bunu test.py adlı bir dosyaya koyun:

#!/usr/bin/python
import subprocess

command = 'php -r "echo gethostname();"'
p = subprocess.Popen(command, universal_newlines=True, shell=True, 
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
text = p.stdout.read()
retcode = p.wait()
print text

Çağırmak:

python test.py

Apollo olan ana bilgisayar adımı yazdırır:

apollo

Alt işlem için el kitabını okuyun: http://docs.python.org/2/library/subprocess.html


5
2017-12-10 05:20





Tek tırnak kullanın 'around the "whole pattern"' otomatik olarak çiftlerden kaçmak veya açıkça "escape the \"double quotes\"". Senin sorununun hiçbir ilgisi yok Popen gibi.

Sadece kayıt için özellikle bir problemim vardı. listtabanlı komut geçti Popen Bu olur değil Bir glob kalıbı etrafında uygun çift tırnakları koruyun (örn. kabul edilen cevapWindows altında. Listeyi bir dizeye ekleyerek ' '.join(cmd) geçmeden önce Popen sorunu çözdü.


3
2017-08-23 08:45



Bu benim için çalışan cevap. yapmak zorundaydım subprocess.run(" ".join(cmd), shell=True) Çalışmak için. Başka hiçbir şey işe yaramadı. - RPGillespie


Benzer bir sorunla, nispeten karmaşık bir çalışma ile çalışıyorum. ssh komutu. Ayrıca çoktan çift tırnak ve tek tırnaklar vardı. Çünkü Komutu borudan geçiriyordum python, ssh, powershell vb.

Bunun yerine komutu sadece bir kabuk komut dosyasına dönüştürebilir ve kabuk komut dosyası aracılığıyla subprocess.call/Popen/runBu sorunlar ortadan kalkacak.

Yani windows veya linux veya mac üzerinde olup olmadığına bağlı olarak bir kabuk komut dosyasında aşağıdakileri de (script.sh veya script.bat)

ffmpeg -i "concat:1.ts|2.ts" -vcodec copy -acodec copy temp.mp4

Sonra koşabilirsin

import subprocess; subprocess.call(`./script.sh`; shell=True)

Tek tırnak vb hakkında endişelenmenize gerek kalmadan


1
2018-03-17 22:20





Ayrıca boşluk içeren ve kullanmak istemeyen bir dize argümanı ile mücadele Kabuk = Gerçek.

Çözüm iç dizeler için çift tırnak kullanmaktı.

args = ['salt', '-G', 'environment:DEV', 'grains.setvals', '{"man_version": "man-dev-2.3"}']

try:
    p = subprocess.Popen(args, stdin=subprocess.PIPE
                             , stdout=subprocess.PIPE
                             , stderr=subprocess.PIPE
                        )
    (stdin,stderr) = p.communicate()
except (subprocess.CalledProcessError, OSError ) as err:
    exit(1)
if p.returncode != 0:
    print("Failure in returncode of command:")

0
2017-07-31 06:50