用子过程捕获Jupyter-Notebook Stdout



我正在努力创建一个工具,该工具允许用户在AWS服务器上使用w/pyspark运行jupyter-notebook,然后将端口转发到其localhost以连接到笔记本。p>我一直在使用subprocess.popen将SSH用于远程服务器并启动Pyspark Shell/Notebook,但是我无法避免将其打印到终端。我想每行执行操作以检索端口号。

例如,在此处运行此操作(在此处遵循最受欢迎的答案:从subprocess.communicate(((读取流媒体输入

command = "jupyter-notebook"
con = subprocess.Popen(['ssh', node, command], stdout=subprocess.PIPE, bufsize=1)
with con.stdout:
    for line in iter(con.stdout.readline, b''):
        print(line),
con.wait()

这忽略了上下文管理器,con部分开始打印出stdout,以便立即将其打印到终端

[I 16:13:20.783 NotebookApp] [nb_conda_kernels] enabled, 0 kernels found
[I 16:13:21.031 NotebookApp] JupyterLab extension loaded from /home/*****/miniconda3/envs/aws/lib/python3.7/site-packages/jupyterlab
[I 16:13:21.031 NotebookApp] JupyterLab application directory is /data/data0/home/*****/miniconda3/envs/aws/share/jupyter/lab
[I 16:13:21.035 NotebookApp] [nb_conda] enabled
...
...
...

当我调用如下随机脚本而不是" jupyter-notebook"(其中 command="bash random_script.sh"(

时,我可以使上下文管理器发挥作用
# random_script.sh
for i in $(seq 1 100)
do
    echo "some output: $i"
    sleep 2
done

这是按预期的,我实际上可以在with语句中的每行执行一项操作。jupyter版本有什么根本不同的东西,可以防止这种情况类似?

这个问题与jupyter产生的游戏机输出实际上是stderr而不是STDOUT的事实有关。我不确定为什么。但是无论如何,这种变化完全解决了问题:

con = subprocess.Popen(['ssh', node, command], 
                       stdout=subprocess.PIPE, 
                       stderr=subprocess.STDOUT,  # <-- redirect stderr to stdout
                       bufsize=1)

最新更新