Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ipython: Can I provide input to a shell command

Can I execute a shell command that requires input in ipython and/or an ipython notebook?

When I execute such a command, I see it's prompt, but no apparent way to provide it with input from my keyboard.

An example could be an rsync command to a remote server (thus requiring a password). There are no doubt dangers security-wise here - these are somewhat reduced in my case as I'm running on localhost.

like image 723
drevicko Avatar asked Sep 20 '13 00:09

drevicko


People also ask

What is IPython interactive shell?

IPython (Interactive Python) is a command shell for interactive computing in multiple programming languages, originally developed for the Python programming language, that offers introspection, rich media, shell syntax, tab completion, and history.

Is IPython an enhanced Interactive Python shell?

The goal of IPython is to create a comprehensive environment for interactive and exploratory computing. To support this goal, IPython has three main components: An enhanced interactive Python shell.


2 Answers

Reposting as an answer, with a bit more detail:

No, it's a long standing issue that's really difficult to resolve: github.com/ipython/ipython/issues/514

The issue is roughly that our architecture can't tell when a process is waiting for input, so it doesn't know to prompt the user for input.

You may be able to use pexpect and raw_input to simulate this for specific programs. I.e. if you say what the prompt looks like, it spots that in the output, and asks the user for input to send back to the process. E.g. for Python:

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

I've just given this a brief test - it works, but it's fairly rough. The concept could be improved.

like image 95
Thomas K Avatar answered Oct 11 '22 07:10

Thomas K


Sadly, no.

I couldn't find documentation on this, so I went source-diving. The ipython code that actually performs that transformation is https://github.com/ipython/ipython/blob/master/IPython/core/inputtransformer.py#L208 , specifically:

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)

which, in other words, invokes the underlying shell with everything following the !.

ipython is probably not what you want -- check out this answer for a Python alternate to include in scripts.

like image 30
Christian Ternus Avatar answered Oct 11 '22 09:10

Christian Ternus