python-2.7 - 使用子进程捕获 jupyter-notebook 标准输出
问题描述
我正在创建一个工具,允许用户在 AWS 服务器上运行带有 pyspark 的 jupyter-notebook,并将端口转发到他们的 localhost 以连接到笔记本。
我一直在使用 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
部分开始打印标准输出,以便立即打印到终端
[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)
推荐阅读
- c++ - 如何将字符串从 cpp 发送到 winform 标头中定义的文本框
- angular - Angular2:获取从数组`|`中选择单个对象的管道
- flutter - 我收到一个错误,在 null 上调用了方法 '*'
- python - 如何在 np.where 函数中包含 pandas 数据框列作为参数?
- python - 如何在 Python 中设置不同于 1 的脉冲(VAR 模型中的 IRF)
- security - JWT 刷新令牌。可以自给自足吗?
- javascript - 资源解释为样式表,但在 cloudflare 工作人员中以 MIME 类型 text/html 传输
- javascript - 复杂的加载页面动画
- r - 读取文本文件之间会引入反斜杠
- javascript - 为 analytics.js (google-analytics) 实现子资源完整性 (SRI) Mozilla Obersvatory