79

有没有办法从一个%%bash或其他%%script单元格中访问当前 python 内核中的变量?

也许作为命令行参数或环境变量?

4

7 回答 7

97

Python 变量可以在一个%%bash%%script单元格的第一行访问,因此可以作为命令行参数传递给脚本。例如,使用 bash 你可以这样做:

%%bash -s "$myPythonVar" "$myOtherVar"
echo "This bash script knows about $1 and $2"

命令行选项允许您将-s位置参数传递给 bash,通过$n第 n 个位置参数访问。请注意,实际分配给 bash 位置变量的是str(myPythonVariable). 如果您传递包含引号字符(或其他 bash 敏感字符)的字符串,则需要使用反斜杠(例如:)对它们进行转义\"

引号很重要 - 没有它们,python 变量(字符串表示)在空格上分割,所以如果myPythonVardatetime.datetime带有str(myPythonVar)as"2013-10-30 05:04:09.797507"的,上面的 bash 脚本将接收 3 个位置变量,前两个带有值2013-10-3005:04:09.797507. 它的输出将是:

This bash script knows about 2013-10-30 and 05:04:09.797507

如果要命名变量并且正在运行 linux,请使用以下方法:

%%script env my_bash_variable="$myPythonVariable" bash
echo myPythonVariable\'s value is $my_bash_variable

您可以指定多个变量赋值。再次提防引号和其他类似的事情(这里 bash 会痛苦地抱怨!)。要了解为什么会这样,请参阅env手册页。

于 2013-10-30T05:38:37.957 回答
68

要在 bash 命令中包含 python 变量,!<some command>请使用以下语法运行{<variable>}

In [1]: for i in range(3):
   ...:     !echo {i+1}
   ...:     
1
2
3

虽然这与 OP 的要求略有不同,但它在执行脚本任务时密切相关且有用。 这篇文章有更多关于在 IPython 和 Jupyter 笔记本中使用 shell 命令的重要提示和示例。

于 2016-12-02T12:42:44.540 回答
6

一个问题是,如果您要提供给 bash 的变量是一个列表,那么它不会按预期工作。

例如,在一个 python 单元格中:

l = ['A', 'B', 'C']

然后,如果您将其直接提供给魔术选项,则下一个单元格:

%%bash -s "$l"
for i in $1
do
echo $i
done

它会像这样奇怪地分裂:

['A',
'B',
'C']

最简单的答案是将代码放在大括号内{}以将您的 python 列表转换为 bash 列表,如下所示:

%%bash -s "{" ".join(l)}"
for i in $1
do
echo $i
done

这给出了预期的输出:

A
B
C
于 2018-07-04T13:35:49.400 回答
4

如果像我这样的人最终在这里寻找如何在使用 运行命令时使用 Python 变量!,只需为变量添加前缀 with$就可以了:

!echo $foobar
于 2021-08-10T15:08:04.063 回答
3

只是要注意一个变化,如果您需要将除简单变量之外的其他内容传递给 bash 脚本:

%%bash -s $dict['key1'] $dict['key2'] $dict['key3']

发生了可怕的错误,但是

%%bash -s {dict['key1']} {dict['key2']} {dict['key3']}

效果很好。

于 2018-01-22T15:17:11.833 回答
1

如果你愿意定义一个新的魔法,你可以使用 Python 字符串模板:

from IPython import get_ipython
from IPython.core.magic import register_cell_magic

ipython = get_ipython()


@register_cell_magic
def pybash(line, cell):
    ipython.run_cell_magic('bash', '', cell.format(**globals()))

然后,如果您在 Python 中定义一个变量,例如:

test = 'Python variables'

你可以使用它:

%%pybash
echo '{test} will be expanded'
echo '{{double braces will be replaced with single braces}}'

导致:

Python variables will be expanded
{double braces will be replaced with single braces}
于 2021-04-10T00:20:34.163 回答
0

不,%%script魔法是自动生成的,不会进行任何魔法进程间数据通信。(情况并非如此,%%R但它是同类中的一种单独的魔法,需要R人们格外小心)

但是编写自己的魔法来做到这一点并不难。

于 2013-10-25T07:01:29.220 回答