# Running Scripts from IPython¶

IPython has a %%script cell magic, which lets you run a cell in a subprocess of any interpreter on your system, such as: bash, ruby, perl, zsh, R, etc.

It can even be a script of your own, which expects input on stdin.

In [1]:
import sys


## Basic usage¶

To use it, simply pass a path or shell command to the program you want to run on the %%script line, and the rest of the cell will be run by that script, and stdout/err from the subprocess are captured and displayed.

In [2]:
%%script python2
import sys
print 'hello from Python %s' % sys.version

hello from Python 2.7.9 (default, Jan 29 2015, 06:27:40)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.56)]

In [3]:
%%script python3
import sys
print('hello from Python: %s' % sys.version)

hello from Python: 3.4.2 |Continuum Analytics, Inc.| (default, Oct 21 2014, 17:42:20)
[GCC 4.2.1 (Apple Inc. build 5577)]


IPython also creates aliases for a few common interpreters, such as bash, ruby, perl, etc.

These are all equivalent to %%script <name>

In [4]:
%%ruby
puts "Hello from Ruby #{RUBY_VERSION}"

Hello from Ruby 2.0.0

In [5]:
%%bash
echo "hello from $BASH"  hello from /usr/local/bin/bash  ## Capturing output¶ You can also capture stdout/err from these subprocesses into Python variables, instead of letting them go directly to stdout/err In [6]: %%bash echo "hi, stdout" echo "hello, stderr" >&2  hi, stdout  hello, stderr  In [7]: %%bash --out output --err error echo "hi, stdout" echo "hello, stderr" >&2  In [8]: print(error) print(output)  hello, stderr hi, stdout  ## Background Scripts¶ These scripts can be run in the background, by adding the --bg flag. When you do this, output is discarded unless you use the --out/err flags to store output as above. In [9]: %%ruby --bg --out ruby_lines for n in 1...10 sleep 1 puts "line #{n}" STDOUT.flush end  Starting job # 0 in a separate thread.  When you do store output of a background thread, these are the stdout/err pipes, rather than the text of the output. In [10]: ruby_lines  Out[10]: <open file '<fdopen>', mode 'rb' at 0x10a4be660> In [11]: print(ruby_lines.read())  line 1 line 2 line 3 line 4 line 5 line 6 line 7 line 8 line 9  ## Arguments to subcommand¶ You can pass arguments the subcommand as well, such as this example instructing Python to use integer division from Python 3: In [12]: %%script python2 -Qnew print 1/3  0.333333333333  You can really specify any program for %%script, for instance here is a 'program' that echos the lines of stdin, with delays between each line. In [13]: %%script --bg --out bashout bash -c "while read line; do echo$line; sleep 1; done"
line 1
line 2
line 3
line 4
line 5

Starting job # 2 in a separate thread.


Remember, since the output of a background script is just the stdout pipe, you can read it as lines become available:

In [14]:
import time
tic = time.time()
line = True
while True:
if not line:
break
sys.stdout.write("%.1fs: %s" %(time.time()-tic, line))
sys.stdout.flush()

0.0s: line 1
1.0s: line 2
2.0s: line 3
3.0s: line 4
4.0s: line 5


## Configuring the default ScriptMagics¶

The list of aliased script magics is configurable.

The default is to pick from a few common interpreters, and use them if found, but you can specify your own in ipython_config.py:

c.ScriptMagics.scripts = ['R', 'pypy', 'myprogram']



And if any of these programs do not apear on your default PATH, then you would also need to specify their location with:

c.ScriptMagics.script_paths = {'myprogram': '/opt/path/to/myprogram'}