如何有条件地评估 bash 脚本

Posted

技术标签:

【中文标题】如何有条件地评估 bash 脚本【英文标题】:How to conditionally evaluate bash script 【发布时间】:2017-03-13 11:49:00 【问题描述】:

要查看环境中已安装的库,我在 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

更新: 在 check_call 内运行 pip freeze 返回 0 个结果:

跑步

    %%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']))

【问题讨论】:

【参考方案1】:

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

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

那么你的函数就可以在任何 Python 环境中工作了。

【讨论】:

@blue-sky 当命令成功时,check_call 的结果代码为零,因此完全正确(但显然不是您所期望的;但是接下来您 做什么期待?) 虽然你想避免不必要和讨厌的shell=True;见***.com/questions/3172470/… @blue-sky:试试更新的版本——显式打印。【参考方案2】:

简短的解释是笔记本有交互式命令,由笔记本本身处理,在 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 的缺失,因为我们不需要或不需要这里的外壳。)

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

旧版本的 Python 在 subprocess.Popen 周围有多种特殊用途的包装器集合,例如 check_callcheck_output 等,但在最近的版本中,这些都被 subprocess.run 所包含。如果您需要支持 3.5 之前的 Python 版本,旧功能仍然可用,但可以说在新代码中应避免使用它们。

【讨论】:

以上是关于如何有条件地评估 bash 脚本的主要内容,如果未能解决你的问题,请参考以下文章

有条件地评估条件 SQL

如何在 Python 2.7 中评估 BASH-Like 命令 (if/elif/else) 语句

使用 cygwin 和 git bash 在 Windows 10 上进行 Shell 脚本评估失败

Python 会懒惰地评估 if 的条件吗? [复制]

在 Spring bean 有条件地设置属性值时,SpEL 条件运算符未按预期进行评估(使用 XML 配置)

评估驱动器是不是正在使用中