为什么 spawn 子进程仅在使用 Python 执行后才打印到标准输出?
Why does the spawn child process print to stdout only after execution with Python?
我创建了以下 node.js
代码,其中包含执行 bash
代码的 spawn 子进程:
const spawn = require('child_process').spawn
const shellcode = `
file=$(mktemp)
cat > $file <<- "EOF"
echo "Hello World"
sleep 2
echo "Hello World"
sleep 2
echo "Hello World"
sleep 2
echo "Hello World"
EOF
bash $file
`
const child = spawn('/bin/bash', [ '-c', shellcode ])
child.stdout.on('data', (data) => {
console.log(data.toString())
})
它工作得很好,它在 shellcode
变量中执行 bash
并打印 Hello World
而 node.js
代码是 运行。
我的问题始于 Python
,我创建了以下代码:
const spawn = require('child_process').spawn
const shellcode = `
file=$(mktemp)
cat > $file <<- "EOF"
import os
print('Hello World')
os.system("sleep 2")
print('Hello World')
os.system("sleep 2")
print('Hello World')
os.system("sleep 2")
print('Hello World')
EOF
python3 $file
`
const child = spawn('/bin/bash', [ '-c', shellcode ])
child.stdout.on('data', (data) => {
console.log(data.toString())
})
但是,此代码不会作为 spawn
代码执行。它等待进程完成以将结果打印到标准输出。我还使用 shellcode
变量中的 node.js 代码测试了相同的逻辑,它工作正常,就像 bash 一样。我错了什么?我不确定这是 Python
问题还是 node.js
问题。为什么 Python
代码不作为 spawn 运行(它正在等待进程完成以打印其输出)?
Python 默认缓冲其输出。
运行 python -u ...
或将 PYTHONUNBUFFERED
环境变量设置为 1
.
顺便说一句,这里根本没有理由使用 bash
– Python 可以愉快地从标准输入读取代码并在没有临时文件的情况下执行它:
const spawn = require('child_process').spawn
const shellcode = `
import os, time
print('Hello 1')
time.sleep(2)
print('Hello 2')
time.sleep(2)
print('Hello 3')
time.sleep(2)
print('Hello 4')
`.trim();
const child = spawn('/usr/bin/python3', ['-u', '-'], {stdio: ['pipe', 'pipe', 'inherit']});
child.stdin.write(shellcode);
child.stdin.end();
child.stdout.on('data', (data) => {
console.log(new Date(), data.toString());
});
打印出来(在撰写本文时):
2022-01-19T13:18:16.084Z Hello 1
2022-01-19T13:18:18.088Z Hello 2
2022-01-19T13:18:20.091Z Hello 3
2022-01-19T13:18:22.093Z Hello 4
我创建了以下 node.js
代码,其中包含执行 bash
代码的 spawn 子进程:
const spawn = require('child_process').spawn
const shellcode = `
file=$(mktemp)
cat > $file <<- "EOF"
echo "Hello World"
sleep 2
echo "Hello World"
sleep 2
echo "Hello World"
sleep 2
echo "Hello World"
EOF
bash $file
`
const child = spawn('/bin/bash', [ '-c', shellcode ])
child.stdout.on('data', (data) => {
console.log(data.toString())
})
它工作得很好,它在 shellcode
变量中执行 bash
并打印 Hello World
而 node.js
代码是 运行。
我的问题始于 Python
,我创建了以下代码:
const spawn = require('child_process').spawn
const shellcode = `
file=$(mktemp)
cat > $file <<- "EOF"
import os
print('Hello World')
os.system("sleep 2")
print('Hello World')
os.system("sleep 2")
print('Hello World')
os.system("sleep 2")
print('Hello World')
EOF
python3 $file
`
const child = spawn('/bin/bash', [ '-c', shellcode ])
child.stdout.on('data', (data) => {
console.log(data.toString())
})
但是,此代码不会作为 spawn
代码执行。它等待进程完成以将结果打印到标准输出。我还使用 shellcode
变量中的 node.js 代码测试了相同的逻辑,它工作正常,就像 bash 一样。我错了什么?我不确定这是 Python
问题还是 node.js
问题。为什么 Python
代码不作为 spawn 运行(它正在等待进程完成以打印其输出)?
Python 默认缓冲其输出。
运行 python -u ...
或将 PYTHONUNBUFFERED
环境变量设置为 1
.
顺便说一句,这里根本没有理由使用 bash
– Python 可以愉快地从标准输入读取代码并在没有临时文件的情况下执行它:
const spawn = require('child_process').spawn
const shellcode = `
import os, time
print('Hello 1')
time.sleep(2)
print('Hello 2')
time.sleep(2)
print('Hello 3')
time.sleep(2)
print('Hello 4')
`.trim();
const child = spawn('/usr/bin/python3', ['-u', '-'], {stdio: ['pipe', 'pipe', 'inherit']});
child.stdin.write(shellcode);
child.stdin.end();
child.stdout.on('data', (data) => {
console.log(new Date(), data.toString());
});
打印出来(在撰写本文时):
2022-01-19T13:18:16.084Z Hello 1
2022-01-19T13:18:18.088Z Hello 2
2022-01-19T13:18:20.091Z Hello 3
2022-01-19T13:18:22.093Z Hello 4