如何向 IPython(笔记本)shell 命令提供内联输入?

How do I provide inline input to an IPython (notebook) shell command?

我想将 IPython 笔记本与一些 shell 命令及其输入放在一起。在 bash 提示符下我可以使用 "here-document" 语法:

bash-3.2$ mysql -u root <<END_IPUT
> use mydb;
> show tables;
> END_INPUT

如何在 IPython 中获得相同的效果,特别是在 jupyter notebook 中?我知道如何执行 shell 命令作为 IPython 作为 "line magics" 或“单元格 魔法”,例如:

In [7]:  !! ls -tF
Out[7]:  ['Demo-notebook.ipynb',
          'createdb.sql',
          ...

我查看了 IPython as a system shell,它展示了如何启用一些语法细节。在以下之后,我可以 运行 系统命令而无需预先添加 !!!

# Turn everything in $PATH into an alias; 
# then enable calling aliases without ! or %
%rehashx      
%autocall 2 

但是 none 这有助于为这些内联命令提供输入:此处文档语法在 IPython 中无效,并导致 python SyntaxError .那我该怎么做呢?

bash 单元格魔法允许您输入多行 bash。只需以 %%bash:

开始任何单元格
%%bash
echo "This is bash"
ls

如果您使用 heredoc 将文本通过管道传输到另一个程序,您还可以使用脚本单元魔术:

%%script bc
2+3

可能还有其他细胞魔法可以更具体地解决您的问题!

通过更多的研究,并借助@ThomasK 的提示(参见接受的答案),我找到了几种方法来做到这一点。

  • 一个解决方案是细胞魔法%sx。它将单元格内容作为 bash 脚本执行,并捕获和 returns 输出作为行列表。有时方便,有时不方便。

    In[1]:  %%sx
            echo Hello, world
            cat -n <<DATA
            this
            and that
            DATA
    
    Out[1]: ['Hello, world', '     1\tthis', '     2\tand that']
    
  • 按照 @ThomasK 的建议将其更改为 %%bash,输出将打印出来,而不是返回。为了捕获它以供进一步处理,ipython 提供了 --out 参数。但是我需要自己打印它——默认情况下它不会显示。

    In[1]:  %%bash --out var
            echo Hello, world
            echo "   Again"
    
    In[2]:  var
    
    Out[2]: 'Hello, world\n   Again\n'
    
  • %%bash 实际上是 %%script bash 的 shorthand,据称工作 "like the #! line in a script"(请参阅 %%script? 的帮助)。它是做什么的。因此,这里介绍了如何免除 here-document 语法并让任何程序读取单元格内容作为输入。 %%script 也接受 --out 参数。

            %%script --out var mysql -u root -p XYZ
            USE somedb;
            SELECT * FROM users
                 WHERE passwd IS NULL\G
    

这很好,但我最终没有使用它,因为我的用例是 mysql,最终我发现有一个很棒的第三方 ipython-sql 扩展可以代替:

%load_ext sql
%sql mysql+pymysql://user:passwd@localhost/somedb

这以安装扩展为前提,pip install ipython-sql。对于 mysql,我还需要 pip install pymysql。经过上面的设置,我就这样和数据库对话了

In[1]:  %%sql 
        SELECT * FROM users
            WHERE passwd IS NULL

Out[1]: 1 rows affected.
        ...

返回的table其实是成带边框的笔记本table,挺好看的。它作为 Pandas 数据框(智能列表)提供,我可以从 _ 中获取它。