¿Por qué el proceso hijo aparece en la consola solo después de la ejecución con Python?
He creado el siguiente código de node.js
con el proceso secundario spawn que ejecuta un código de bash
dentro de él:
const spawn = require('child_process').spawn
const shellcode = `
file=$(mktemp)
cat > $file <<- "EOF"
echo "Hola Mundo"
sleep 2
echo "Hola Mundo"
sleep 2
echo "Hola Mundo"
sleep 2
echo "Hola Mundo"
EOF`
bash $file
`
const child = spawn('/bin/bash', ['-c', shellcode])
child.stdout.on('data', (data) => {
console.log(data.toString())
})
Funciona perfectamente, ejecuta el bash
dentro de la variable shellcode
e imprime “Hola Mundo” mientras se está ejecutando el código node.js
.
Mi problema comienza con Python
, he creado el siguiente código:
const spawn = require('child_process').spawn
const shellcode = `
file=$(mktemp)
cat > $file <<- "EOF"
import os
print('Hola Mundo')
os.system("sleep 2")
print('Hola Mundo')
os.system("sleep 2")
print('Hola Mundo')
os.system("sleep 2")
print('Hola Mundo')
EOF`
python3 $file
`
const child = spawn('/bin/bash', ['-c', shellcode])
child.stdout.on('data', (data) => {
console.log(data.toString())
})
Sin embargo, este código no se ejecuta como un código de spawn
. Espera a que el proceso termine para imprimir los resultados en la salida estándar. También he probado la misma lógica con un código de node.js dentro de la variable shellcode
y funciona bien, al igual que bash. ¿Qué estoy haciendo mal? No estoy seguro si es un problema de Python
o si es un problema de node.js
. ¿Por qué el código de Python
no se comporta como un spawn (espera a que el proceso termine para imprimir su salida)?
davy.ai
Hay algunas cosas que debes tener en cuenta aquí. En primer lugar, la función
spawn
enchild_process
está específicamente diseñada para generar procesos secundarios y transmitir su salida al proceso principal, por lo que no es sorprendente que tu código Bash funcione bien con eso.Sin embargo, en lo que respecta a tu código de Python, hay algunas cuestiones. En primer lugar, el código que has escrito no es una sintaxis válida de Bash, por lo que no se ejecutará correctamente. Específicamente, el comando
cat
debería ir seguido de un delimitador de documentos en línea (EOF
en este caso) sin espacios, por lo que tu código debe lucir así:una vez que hayas corregido este problema, deberías poder ejecutar el código de python como un proceso secundario utilizando
spawn
. sin embargo, hay otro problema del cual debes ser consciente: cuando ejecutas un script de python utilizandopython3
en una terminalbash
, el intérprete de python hereda en realidad los flujos de entrada/salida de la terminal principal. esto significa que, cuando ejecutas el script utilizandospawn
, la salida de tu script de python se almacena en búfer hasta que se complete el script.para solucionar este problema, debes vaciar explícitamente el búfer de salida de stdout después de cada llamada a
print
, así:con estos cambios, tu código de python debería ejecutarse como un proceso secundario utilizando
spawn
y transmitir su salida al proceso principal. import=”” os=”” print(‘hola=”” mundo’)=”” os.system(“sleep=”” 2″)=”” print(‘hola=”” mundo’)=”” os.system(“sleep=”” 2″)=”” print(‘hola=”” mundo’)=”” os.system(“sleep=”” 2″)=”” print(‘hola=”” mundo’)=”” eof=”” python3=”” $file=””="" una="" vez="" que="" hayas="" corregido="" este="" problema,="" deberías="" poder="" ejecutar="" el="" código="" de="" python="" como="" un="" proceso="" secundario="" utilizando="" `spawn`.="" sin="" embargo,="" hay="" otro="" problema="" del="" cual="" debes="" ser="" consciente:="" cuando="" ejecutas="" un="" script="" de="" python="" utilizando="" `python3`="" en="" una="" terminal="" `bash`,="" el="" intérprete="" de="" python="" hereda="" en="" realidad="" los="" flujos="" de="" entrada/salida="" de="" la="" terminal="" principal.="" esto="" significa="" que,="" cuando="" ejecutas="" el="" script="" utilizando="" `spawn`,="" la="" salida="" de="" tu="" script="" de="" python="" se="" almacena="" en="" búfer="" hasta="" que="" se="" complete="" el="" script.="" para="" solucionar="" este="" problema,="" debes="" vaciar="" explícitamente="" el="" búfer="" de="" salida="" de="" stdout="" después="" de="" cada="" llamada="" a="" `print`,="" así:=""
python=”” import=”” os=”” import=”” sys=”” print(‘hola=”” mundo’,=”” flush=”True)” os.system(“sleep=”” 2″)=”” print(‘hola=”” mundo’,=”” flush=”True)” os.system(“sleep=”” 2″)=”” print(‘hola=”” mundo’,=”” flush=”True)” os.system(“sleep=”” 2″)=”” print(‘hola=”” mundo’,=”” flush=”True)” sys.stdout.flush()=”” “`=”” con=”” estos=”” cambios,=”” tu=”” código=”” de=”” python=”” debería=”” ejecutarse=”” como=”” un=”” proceso=”” secundario=”” utilizando=””spawn
=”” y=”” transmitir=”” su=”” salida=”” al=”” proceso=””></eofimport os
print(‘hola mundo’)
os.system(“sleep 2”)
print(‘hola mundo’)
os.system(“sleep 2”)
print(‘hola mundo’)
os.system(“sleep 2”)
print(‘hola mundo’)
eof
python3 $file
con estos cambios, tu código de python debería ejecutarse como un proceso secundario utilizando
spawn
y transmitir su salida al proceso principal.>