ipython:我可以为shell命令提供输入吗?

时间:2013-09-20 00:28:42

标签: shell ipython ipython-notebook

我可以执行需要在ipython和/或ipython笔记本中输入的shell命令吗?

当我执行这样的命令时,我看到它的提示,但没有明显的方法来提供键盘输入。

示例可以是远程服务器的rsync命令(因此需要密码)。毫无疑问,这里存在安全方面的危险 - 在我的案例中,由于我在localhost上运行,这些有所减少。

4 个答案:

答案 0 :(得分:3)

重新作为答案,更详细一点:

不,这是一个很难解决的长期问题:github.com/ipython/ipython/issues/514

问题大致是我们的架构无法判断进程何时等待输入,因此它不知道提示用户输入。

您可以使用pexpect和raw_input来模拟特定程序。即如果您说出提示符的样子,它会在输出中找到它,并要求用户输入以发送回进程。例如。对于Python:

import pexpect
p = pexpect.spawn('python')
while True:
    try:
        p.expect('\n>>> ')
        print(p.before)
        p.sendline(raw_input('>>> '))
    except pexpect.EOF:
        break

我刚刚给出了一个简短的测试 - 它有效,但它相当粗糙。这个概念可以改进。

答案 1 :(得分:1)

可悲的是,没有。

我找不到关于此的文档,所以我去了潜水源。实际执行该转换的ipython代码是https://github.com/ipython/ipython/blob/master/IPython/core/inputtransformer.py#L208,具体为:

def _tr_system(line_info):
    "Translate lines escaped with: !"
    cmd = line_info.line.lstrip().lstrip(ESC_SHELL)
    return '%sget_ipython().system(%r)' % (line_info.pre, cmd)
换句话说,使用!之后的所有内容调用底层shell。

ipython可能不是您想要的 - 请查看this answer以获取包含在脚本中的Python备用文件。

答案 2 :(得分:1)

当我看到它有点问题时,只是在寻找这个,我的脸就掉了下来。以为我会发布我的解决方案,以防它对任何人都有用。

基本上我一直在寻找一种通过笔记本发送sudo命令的方法,可能不是很明智,但我需要它来做我正在做的事情。我无法得到密码提示。所以决定使用x-terminal并将命令发送到终端。您没有得到任何反馈,但可能是因为在回来的路上没有连接到IO。这是我在笔记本中使用的内容:

在[1] !xterm -e sudo mount -o loop system.img /system/

我正在使用linux,但我希望Windows !cmd也可以做到这一点

答案 3 :(得分:1)

许多需要密码的程序提供了多种方法来提示用户,以便jupyter不必为您执行此操作。 sudo命令具有-A选项和SUDO_ASKPASS环境变量。我已经像这样使用sudo来获取/var/log/btmp.1文件的权限:

 In [1]: !SUDO_ASKPASS=/usr/bin/ssh-askpass sudo -A lastb -a -f /var/log/btmp.1 | head

同样,对于您的情况,ssh有一个SSH_ASKPASS环境变量。

请注意,对于ssh / rsync的无头操作,您可以通过直接设置ssh代理(如果它尚未运行)并使用{{1}引用它来完全避免来自笔记本的身份验证提示变量,就像SSH_AUTH_SOCK一样。 或者您可以通过ssh-add使用其他程序,以自定义方式处理身份验证。有关详细信息,请参阅How to automate SSH login with password? - Server Fault之类的问题,但请注意不要损害您的安全性,尤其是在尝试自动连接从一台服务器到另一台服务器时。