separar - reemplazar caracteres en python
Pasar comandos de shell de comillas dobles en python para subprocesar.Popen()? (5)
He intentado pasar un comando que funciona en shell que solo funciona con comillas dobles en la línea de comandos alrededor del argumento "concat:file1|file2"
para ffmpeg.
Sin embargo, no puedo hacer que esto funcione desde python con subprocess.Popen()
. Alguien tiene una idea de cómo se pasan las cotizaciones al subproceso. ¿Pobre?
Aquí está el código:
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()
Cuando hago esto, ffmpeg no lo tomará de otra forma que no sea una cita alrededor del seudo concat. ¿Hay alguna manera de pasar con éxito esta línea al subproceso. ¿Comando Polar?
Esto funciona con python 2.7.3. El comando de pipe stderr a stdout ha cambiado desde versiones anteriores de python:
Pon esto en un archivo llamado test.py:
#!/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
Invocarlo:
python test.py
Imprime mi nombre de host, que es apollo:
apollo
Lea el manual del subproceso: http://docs.python.org/2/library/subprocess.html
He estado trabajando con un problema similar, con ejecutar un comando relativamente complejo sobre ssh. También tenía comillas dobles y comillas simples. Porque estaba canalizando el comando a través de python
, ssh
, powershell
, etc.
Si puede convertir el comando en un script de shell y ejecutar el script de shell a través de subprocess.call/Popen/run
, estos problemas desaparecerán.
De modo que, dependiendo de si está en Windows o en Linux o Mac, coloque lo siguiente en un script de shell ( script.sh
o script.bat
)
ffmpeg -i "concat:1.ts|2.ts" -vcodec copy -acodec copy temp.mp4
Entonces puedes correr
import subprocess; subprocess.call(`./script.sh`; shell=True)
Sin tener que preocuparse por las comillas simples, etc.
Sugeriría utilizar la forma de invocación de lista en lugar de la versión de cadena entrecomillada:
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()
Esto representa con mayor precisión el conjunto exacto de parámetros que se pasarán al proceso final y elimina la necesidad de perder el tiempo con las cotizaciones de shell.
Dicho eso, si deseas usar la versión de cadena simple, simplemente utiliza diferentes comillas (y 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()
También lucha con un argumento de cadena que contiene espacios y no quiere usar el intérprete = Verdadero .
La solución fue usar comillas dobles para las cadenas internas.
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:")
Utilice comillas simples ''around the "whole pattern"''
para escapar automáticamente de los dobles o explícitamente "escape the /"double quotes/""
. Tu problema no tiene nada que ver con Popen
como tal.
Solo para el registro, tuve un problema particularmente con un comando basado en list
pasado a Popen
que no conservaría las comillas dobles adecuadas alrededor de un patrón global (es decir, lo que se sugirió en la respuesta aceptada ) en Windows. Unir la lista en una cadena con '' ''.join(cmd)
antes de pasarla a Popen
resolvió el problema.