如何有条件地评估bash脚本

时间:2017-03-13 11:49:01

标签: python pyspark jupyter-notebook jupyter ipywidgets

要在环境中查看已安装的库,我在Jupyter Python笔记本单元格中运行此代码:

%%bash
pip freeze

这有效,但如何有条件地执行此代码?

这是我的尝试:

from __future__ import print_function
from ipywidgets import interact, interactive, fixed, interact_manual
import ipywidgets as widgets

def f(x1):
    if(x1 == True):
        f2()
    return x1

interact(f , x1 = False)


def f2():
    %%bash 
    pip freeze

但是评估单元格会引发错误:

  File "<ipython-input-186-e8a8ec97ab2d>", line 15
    pip freeze
             ^
SyntaxError: invalid syntax

使用ipywidgets生成复选框:https://github.com/ipython/ipywidgets

更新: 在pip freeze内运行check_call会返回0结果: enter image description here

运行

    %%bash 
    pip freeze

返回已安装的库,因此0不正确。

subprocess.check_call("pip freeze", shell=True)是否正确?

更新2:

这有效:

from __future__ import print_function
from ipywidgets import interact, interactive, fixed, interact_manual
import ipywidgets as widgets
import subprocess

def f(View):
    if(View == True):
        f2()

interact(f , View = False)


def f2():
    print(subprocess.check_output(['pip', 'freeze']))

2 个答案:

答案 0 :(得分:2)

您可以使用标准的Python方式:

import subprocess
print(subprocess.check_output(['pip', 'freeze']))

然后您的函数将在任何Python环境中工作。

答案 1 :(得分:1)

简短的解释是笔记本具有交互式命令,这些命令由笔记本本身处理,然后Python解释器才会看到它们。 %%bash就是这样一个命令的一个例子;你不能把它放在Python代码中,因为它不是Python。

使用bash实际上并没有在本身添加任何内容; 使用shell提供了许多互动优势,当然,在交互式笔记本中,提供用户访问权限shell是一种允许用户执行外部进程的强大机制;但在这种特殊情况下,使用非交互式执行,将shell放在你自己和pip之间没有实际好处,所以你可能只想要

 import subprocess
 if some_condition:
     p = subprocess.run(['pip', 'freeze'],
         stdout=subprocess.PIPE, universal_newlines=True)

(请注意shell=True的缺席,因为我们在这里不需要或不需要shell。)

如果您想要捕获的退出代码或pip freeze的输出,则它们可用作返回对象p的属性。有关详细信息,请参阅subprocess.run documentation。简而言之,如果命令成功,p.returncode将为0,输出将在p.stdout中。

旧版本的Python在subprocess.Popen check_callcheck_output周围有各种各样的特殊用途包装,但这些包装都由subprocess.run包含在=IF(countif(INDEX('OtherWorkSheet'!$G:$H,I$8,0),"Yes")+countif(INDEX('OtherWorkSheet'!$J:$L,I$8,0),"Yes") > 1, "Y", "N" ) 中。最新版本。如果你需要在3.5之前支持Python版本,遗留功能仍然可用,但在新代码中应该可以避免它们。