1 votos

Python 'subprocess.run' falla con CalledProcessError en Mac pero funciona en Windows

Tengo un archivo de script subprocess-script.py de la siguiente manera:

import subprocess
import platform

command = []
exe = "ruta/a/miapp.app"
input = "/ruta/a/in.ext"
output = "/ruta/a/out.ext"

command.append('open')
command.append('-a')
command.append(f'"{exe}"')
command.append('--args')
command.append("--input")
command.append(f'"{input}"')
command.append("--output")
command.append(f'"{output}"')
command.append('-report')

print("EJECUTAR: ", " ".join(command))

subprocess.run(command, shell=True, check=True, capture_output=True, text=True)

Ejecuto el script usando el comando python3 subprocess-script.py y obtengo la siguiente excepción:

user@macbookair ~ % python3 subprocess-script.py
EJECUTAR:  open -a "ruta/a/miapp.app" --args --input "/ruta/a/in.ext" --output "/ruta/a/out.ext"
Traceback (most recent call last):
  File "/ruta/a/subprocess-script.py", línea XX, in 
    result = subprocess.run(command, shell=True, check=True, capture_output=True, text=True)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/Cellar/python@3.11/3.11.7_1/Frameworks/Python.framework/Versions/3.11/lib/python3.11/subprocess.py", línea 571, en run
    raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: ¡El comando '['open', '-a', '"ruta/a/miapp.app"', '--args', '--input', '"/ruta/a/in.ext"', '--output', '"/ruta/a/out.ext"']' devolvió un estado de salida distinto de cero 1.
user@macbookair ~ %

Pero cuando tomo la declaración de impresión EJECUTAR y pruebo la declaración, funciona perfectamente y genera mi archivo de salida out.ext:

open -a "ruta/a/miapp.app" --args --input "/ruta/a/in.ext" --output "/ruta/a/out.ext"

Sospecho que estoy construyendo el comando incorrectamente? Toma nota de que uso comillas para mis rutas intencionalmente porque a veces las rutas contienen carpetas con espacios y eso fallará si no están encerradas entre comillas. También probé la bandera -report como se menciona en este hilo pero no veo ningún archivo de registro generado. Esta información está ausente en la respuesta. Hay una solución potencial en este hilo donde la lista de comandos se transforma en una cadena usando " ".join(command) pero no estoy seguro si esto es una solución temporal o la solución adecuada.

En Windows no tengo un problema donde construyo el comando de esta manera:

command.append('powershell')
command.append('-Command')
command.append(f'& "{exe}"')
command.append('--args')
command.append("--input")
command.append(f'"{input}"')
command.append("--output")
command.append(f'"{output}"')

¿Cuál podría ser el problema en la versión de Mac del script?

1voto

Estás construyendo diferentes comandos en Windows y en macOS. El equivalente de macOS del comando PowerShell es

subprocess.run(["bash", "-c", "ls \"File Name.txt\""])

Esto requeriría comillas adicionales alrededor de las rutas/archivos para proteger cualquier espacio en blanco del shell.

Pero cuando uses open, no hay implicado un shell e intenta ejecutar "path/to/myapp.app" que no existe (path/to/myapp.app sí).

Así que o usas el enfoque de bash en macOS (y entrecomillas las rutas), o usas open sin entrecomillar las rutas.

PD: Lo más probable es que no necesites ninguno de los dos, también puedes simplemente ejecutar

subprocess.run(["path/to/myapp.app", "--args", "--input", f'{input}'])

0voto

Harry McKenzie Puntos 111

Deberá navegar hasta el directorio Contents/MacOS/ dentro del paquete de la aplicación y ejecutar directamente el binario. Este directorio típicamente contiene el ejecutable principal de la aplicación.

comando = []

exe = "/ruta a la aplicación que podría contener espacios/miapp.app/Contents/MacOS/binario-de-app"

comando.append("--input")
comando.append(f'"{entrada}"')
comando.append("--output")
comando.append(f'"{salida}"')

comando_str = " ".join(comando)

print("EJECUTAR: ", comando_str)

# subprocess.run(comando) # tenga en cuenta que esto no funcionará por alguna razón desconocida, al menos para el binario vengi-voxconvert en https://github.com/vengi-voxel/vengi/releases/download/v0.0.28/vengi-0.0.28-Darwin.dmg
subprocess.run(comando_str, shell=True, check=True, capture_output=True, text=True)

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X