from - run python script mac
En Python, ¿cómo uso subproceso en lugar de os.system? (7)
Eliminar citas del nombre del ejecutable. En la primera línea de tu ejemplo, en lugar de
sqlpubwiz = r''"C:/Program Files/Microsoft SQL Server/90/Tools/Publishing/sqlpubwiz.exe"''
utilizar:
sqlpubwiz = r''C:/Program Files/Microsoft SQL Server/90/Tools/Publishing/sqlpubwiz.exe''
Eso es porque no tienes que escapar de nada ya que un caparazón no estará involucrado.
Entonces simplemente use subprocess.call(args)
(no se join
los argumentos, páselos como una lista)
Si desea capturar el resultado (el sistema os.system
no puede hacerlo) simplemente siga la documentación del subproceso :
result = subprocess.Popen(args, stdout=subprocess.PIPE).communicate()[0]
print result
Tengo un script de Python que llama a un programa ejecutable con varios argumentos (en este ejemplo, es ''sqlpubwiz.exe'' que es el "Asistente de publicación de base de datos de Microsoft SQL Server"):
import os
sqlpubwiz = r''"C:/Program Files/Microsoft SQL Server/90/Tools/Publishing/sqlpubwiz.exe"''
server = ''myLocalServer''
database = ''myLocalDatabase''
connection_values = [''server='' + server, ''database='' + database, ''trusted_connection=true'']
connection_string = '';''.join(connection_values)
dbms_version = ''2000''
sqlscript_filename = ''CreateSchema.sql''
args = [
sqlpubwiz,
''script'',
''-C '' + connection_string,
sqlscript_filename,
''-schemaonly'',
''-targetserver '' + dbms_version,
''-f'',
]
cmd = '' ''.join(args)
os.system(cmd)
Este código se ejecuta correctamente, pero me gustaría adquirir el hábito de usar un subproceso, ya que está destinado a reemplazar os.system. Sin embargo, después de algunos intentos fallidos, parece que no puedo hacer que funcione correctamente.
¿Cómo se vería el código anterior si se convirtiera para usar un subproceso en lugar de os.system?
Esta no es una respuesta directa a su pregunta, pero pensé que podría ser útil.
En caso de que alguna vez desee un control más detallado sobre lo que se devuelve para el manejo de excepciones, etc., también puede consultar a pexpect . Lo he usado en situaciones en las que el proceso al que estaba llamando no necesariamente salía con señales de estado normales, o quería interactuar más con él. Es una función bastante práctica.
Los comandos de Windows aceptarán barras diagonales ''/'' en lugar de barras diagonales inversas en nombres de ruta, por lo que puede usar la anterior para evitar el escape de barras diagonales inversas en las cadenas de comandos. No es exactamente una respuesta a su pregunta, pero tal vez sea útil saberlo.
Para su información, el subprocess
tiene una función list2cmdline()
que le permitirá ver la cadena que Popen
.
Tu versión da:
''"C://Program Files//Microsoft SQL Server//90//Tools//Publishing//sqlpubwiz.exe" script "-C server=myLocalServer;database=myLocalDatabase;trusted_connection=true" CreateSchema.sql -schemaonly "-targetserver 2000" -f''
con citas extra alrededor de "-C server=myLocalServer;database=myLocalDatabase;trusted_connection=true"
y "-targetserver 2000"
.
Correctamente formateado:
args = [
sqlpubwiz,
''script'',
''-C'', connection_string,
sqlscript_filename,
''-schemaonly'',
''-targetserver'', dbms_version,
''-f'',
]
da:
''"C://Program Files//Microsoft SQL Server//90//Tools//Publishing//sqlpubwiz.exe" script -C server=myLocalServer;database=myLocalDatabase;trusted_connection=true CreateSchema.sql -schemaonly -targetserver 2000 -f''
Además, punto menor, pero es una buena costumbre hacer secuencias como args
que no necesitan ser mutables en tuplas en lugar de listas.
Recuerde que os.system usa el shell, por lo que realmente debe pasar
shell=True
al constructor / llamada de Popen para emularlo correctamente. Puede que en realidad no necesites un caparazón, por supuesto, pero ahí está.
import subprocess
p=subprocess.Popen(args, stdout=subprocess.PIPE)
print p.communicate()[0]
Se vería más o menos igual. Pero el camino no debe ser r ''"cualquiera que sea el camino"''. Porque eso me da un error. Desea "el camino con barras invertidas escapadas" o "la ruta sin escaparse".
También args debe tener la forma [''-arg'', ''args''] en lugar de [''arg argsval''].
Debajo está mi código revisado basado en la ayuda y sugerencias de Carlos Rendon (y nosklo ):
# import os
import subprocess
sqlpubwiz = r''C:/Program Files/Microsoft SQL Server/90/Tools/Publishing/sqlpubwiz.exe''
server = ''myLocalServer''
database = ''myLocalDatabase''
connection_values = [''server='' + server, ''database='' + database, ''trusted_connection=true'']
connection_string = '';''.join(connection_values)
dbms_version = ''2000''
sqlscript_filename = ''CreateSchema.sql''
args = [
sqlpubwiz,
''script'',
''-C'',
connection_string,
sqlscript_filename,
''-schemaonly'',
''-targetserver'',
dbms_version,
''-f'',
]
# cmd = '' ''.join(args)
# os.system(cmd)
subprocess.call(args)
(Nota: los valores originales del argumento que contenían espacios necesarios para convertirlos en elementos de lista separados).