Script Magics.ipynb
447 lines
| 8.8 KiB
| text/plain
|
TextLexer
MinRK
|
r7402 | { | |
Min RK
|
r18669 | "cells": [ | |
MinRK
|
r7402 | { | |
Min RK
|
r18669 | "cell_type": "markdown", | |
"metadata": {}, | |||
"source": [ | |||
"# Running Scripts from IPython" | |||
] | |||
}, | |||
{ | |||
"cell_type": "markdown", | |||
"metadata": {}, | |||
"source": [ | |||
"IPython has a `%%script` cell magic, which lets you run a cell in\n", | |||
"a subprocess of any interpreter on your system, such as: bash, ruby, perl, zsh, R, etc.\n", | |||
"\n", | |||
"It can even be a script of your own, which expects input on stdin." | |||
] | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 1, | |||
"metadata": { | |||
"collapsed": false | |||
}, | |||
"outputs": [], | |||
"source": [ | |||
"import sys" | |||
] | |||
}, | |||
{ | |||
"cell_type": "markdown", | |||
"metadata": {}, | |||
"source": [ | |||
"## Basic usage" | |||
] | |||
}, | |||
{ | |||
"cell_type": "markdown", | |||
"metadata": {}, | |||
"source": [ | |||
"To use it, simply pass a path or shell command to the program you want to run on the `%%script` line,\n", | |||
"and the rest of the cell will be run by that script, and stdout/err from the subprocess are captured and displayed." | |||
] | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 2, | |||
"metadata": { | |||
"collapsed": false | |||
}, | |||
"outputs": [ | |||
MinRK
|
r7402 | { | |
Min RK
|
r18669 | "name": "stdout", | |
"output_type": "stream", | |||
"text": [ | |||
"hello from Python 2.7.1 (r271:86832, Jul 31 2011, 19:30:53) \n", | |||
"[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)]\n" | |||
MinRK
|
r7402 | ] | |
Min RK
|
r18669 | } | |
], | |||
"source": [ | |||
"%%script python\n", | |||
"import sys\n", | |||
"print 'hello from Python %s' % sys.version" | |||
] | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 3, | |||
"metadata": { | |||
"collapsed": false | |||
}, | |||
"outputs": [ | |||
MinRK
|
r7402 | { | |
Min RK
|
r18669 | "name": "stdout", | |
"output_type": "stream", | |||
"text": [ | |||
"hello from Python: 3.2.3 (v3.2.3:3d0686d90f55, Apr 10 2012, 11:25:50) \n", | |||
"[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)]\n" | |||
MinRK
|
r7402 | ] | |
Min RK
|
r18669 | } | |
], | |||
"source": [ | |||
"%%script python3\n", | |||
"import sys\n", | |||
"print('hello from Python: %s' % sys.version)" | |||
] | |||
}, | |||
{ | |||
"cell_type": "markdown", | |||
"metadata": {}, | |||
"source": [ | |||
"IPython also creates aliases for a few common interpreters, such as bash, ruby, perl, etc.\n", | |||
"\n", | |||
"These are all equivalent to `%%script <name>`" | |||
] | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 4, | |||
"metadata": { | |||
"collapsed": false | |||
}, | |||
"outputs": [ | |||
Brian Granger
|
r9193 | { | |
Min RK
|
r18669 | "name": "stdout", | |
"output_type": "stream", | |||
"text": [ | |||
"Hello from Ruby 1.8.7\n" | |||
MinRK
|
r7402 | ] | |
Min RK
|
r18669 | } | |
], | |||
"source": [ | |||
"%%ruby\n", | |||
"puts \"Hello from Ruby #{RUBY_VERSION}\"" | |||
] | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 5, | |||
"metadata": { | |||
"collapsed": false | |||
}, | |||
"outputs": [ | |||
MinRK
|
r7402 | { | |
Min RK
|
r18669 | "name": "stdout", | |
"output_type": "stream", | |||
"text": [ | |||
"hello from /usr/local/bin/bash\n" | |||
MinRK
|
r7402 | ] | |
Min RK
|
r18669 | } | |
], | |||
"source": [ | |||
"%%bash\n", | |||
"echo \"hello from $BASH\"" | |||
] | |||
}, | |||
{ | |||
"cell_type": "markdown", | |||
"metadata": {}, | |||
"source": [ | |||
"## Capturing output" | |||
] | |||
}, | |||
{ | |||
"cell_type": "markdown", | |||
"metadata": {}, | |||
"source": [ | |||
"You can also capture stdout/err from these subprocesses into Python variables, instead of letting them go directly to stdout/err" | |||
] | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 6, | |||
"metadata": { | |||
"collapsed": false | |||
}, | |||
"outputs": [ | |||
MinRK
|
r7402 | { | |
Min RK
|
r18669 | "name": "stdout", | |
"output_type": "stream", | |||
"text": [ | |||
"hi, stdout\n" | |||
MinRK
|
r7402 | ] | |
}, | |||
{ | |||
Min RK
|
r18669 | "name": "stderr", | |
"output_type": "stream", | |||
"text": [ | |||
"hello, stderr\n" | |||
MinRK
|
r7402 | ] | |
Min RK
|
r18669 | } | |
], | |||
"source": [ | |||
"%%bash\n", | |||
"echo \"hi, stdout\"\n", | |||
"echo \"hello, stderr\" >&2\n" | |||
] | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 7, | |||
"metadata": { | |||
"collapsed": false | |||
}, | |||
"outputs": [], | |||
"source": [ | |||
"%%bash --out output --err error\n", | |||
"echo \"hi, stdout\"\n", | |||
"echo \"hello, stderr\" >&2" | |||
] | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 8, | |||
"metadata": { | |||
"collapsed": false | |||
}, | |||
"outputs": [ | |||
MinRK
|
r7402 | { | |
Min RK
|
r18669 | "name": "stdout", | |
"output_type": "stream", | |||
"text": [ | |||
"hello, stderr\n", | |||
MinRK
|
r7739 | "\n", | |
Min RK
|
r18669 | "hi, stdout\n", | |
"\n" | |||
MinRK
|
r7402 | ] | |
Min RK
|
r18669 | } | |
], | |||
"source": [ | |||
"print(error)\n", | |||
"print(output)" | |||
] | |||
}, | |||
{ | |||
"cell_type": "markdown", | |||
"metadata": {}, | |||
"source": [ | |||
"## Background Scripts" | |||
] | |||
}, | |||
{ | |||
"cell_type": "markdown", | |||
"metadata": {}, | |||
"source": [ | |||
"These scripts can be run in the background, by adding the `--bg` flag.\n", | |||
"\n", | |||
"When you do this, output is discarded unless you use the `--out/err`\n", | |||
"flags to store output as above." | |||
] | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 9, | |||
"metadata": { | |||
"collapsed": false | |||
}, | |||
"outputs": [ | |||
MinRK
|
r7402 | { | |
Min RK
|
r18669 | "name": "stdout", | |
"output_type": "stream", | |||
"text": [ | |||
"Starting job # 0 in a separate thread.\n" | |||
MinRK
|
r7402 | ] | |
Min RK
|
r18669 | } | |
], | |||
"source": [ | |||
"%%ruby --bg --out ruby_lines\n", | |||
"for n in 1...10\n", | |||
" sleep 1\n", | |||
" puts \"line #{n}\"\n", | |||
" STDOUT.flush\n", | |||
"end" | |||
] | |||
}, | |||
{ | |||
"cell_type": "markdown", | |||
"metadata": {}, | |||
"source": [ | |||
"When you do store output of a background thread, these are the stdout/err *pipes*,\n", | |||
"rather than the text of the output." | |||
] | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 10, | |||
"metadata": { | |||
"collapsed": false | |||
}, | |||
"outputs": [ | |||
MinRK
|
r7402 | { | |
Min RK
|
r18669 | "data": { | |
"text/plain": [ | |||
"<open file '<fdopen>', mode 'rb' at 0x10a4be660>" | |||
] | |||
}, | |||
"execution_count": 10, | |||
MinRK
|
r7739 | "metadata": {}, | |
Min RK
|
r18669 | "output_type": "execute_result" | |
} | |||
], | |||
"source": [ | |||
"ruby_lines" | |||
] | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 11, | |||
"metadata": { | |||
"collapsed": false | |||
}, | |||
"outputs": [ | |||
MinRK
|
r7402 | { | |
Min RK
|
r18669 | "name": "stdout", | |
"output_type": "stream", | |||
"text": [ | |||
MinRK
|
r7739 | "line 1\n", | |
"line 2\n", | |||
"line 3\n", | |||
"line 4\n", | |||
Min RK
|
r18669 | "line 5\n", | |
"line 6\n", | |||
"line 7\n", | |||
"line 8\n", | |||
"line 9\n", | |||
"\n" | |||
MinRK
|
r7402 | ] | |
Min RK
|
r18669 | } | |
], | |||
"source": [ | |||
"print(ruby_lines.read())" | |||
] | |||
}, | |||
{ | |||
"cell_type": "markdown", | |||
"metadata": {}, | |||
"source": [ | |||
"## Arguments to subcommand" | |||
] | |||
}, | |||
{ | |||
"cell_type": "markdown", | |||
"metadata": {}, | |||
"source": [ | |||
"You can pass arguments the subcommand as well,\n", | |||
"such as this example instructing Python to use integer division from Python 3:" | |||
] | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 12, | |||
"metadata": { | |||
"collapsed": false | |||
}, | |||
"outputs": [ | |||
MinRK
|
r7402 | { | |
Min RK
|
r18669 | "name": "stdout", | |
"output_type": "stream", | |||
"text": [ | |||
"0.333333333333\n" | |||
] | |||
} | |||
], | |||
"source": [ | |||
"%%script python -Qnew\n", | |||
"print 1/3" | |||
] | |||
}, | |||
{ | |||
"cell_type": "markdown", | |||
"metadata": {}, | |||
"source": [ | |||
"You can really specify *any* program for `%%script`,\n", | |||
"for instance here is a 'program' that echos the lines of stdin, with delays between each line." | |||
] | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 13, | |||
"metadata": { | |||
"collapsed": false | |||
}, | |||
"outputs": [ | |||
MinRK
|
r7402 | { | |
Min RK
|
r18669 | "name": "stdout", | |
"output_type": "stream", | |||
"text": [ | |||
"Starting job # 2 in a separate thread.\n" | |||
MinRK
|
r7402 | ] | |
Min RK
|
r18669 | } | |
], | |||
"source": [ | |||
"%%script --bg --out bashout bash -c \"while read line; do echo $line; sleep 1; done\"\n", | |||
"line 1\n", | |||
"line 2\n", | |||
"line 3\n", | |||
"line 4\n", | |||
"line 5\n" | |||
] | |||
}, | |||
{ | |||
"cell_type": "markdown", | |||
"metadata": {}, | |||
"source": [ | |||
"Remember, since the output of a background script is just the stdout pipe,\n", | |||
"you can read it as lines become available:" | |||
] | |||
}, | |||
{ | |||
"cell_type": "code", | |||
"execution_count": 14, | |||
"metadata": { | |||
"collapsed": false | |||
}, | |||
"outputs": [ | |||
MinRK
|
r7402 | { | |
Min RK
|
r18669 | "name": "stdout", | |
"output_type": "stream", | |||
"text": [ | |||
"0.0s: line 1\n", | |||
"1.0s: line 2\n", | |||
"2.0s: line 3\n", | |||
"3.0s: line 4\n", | |||
"4.0s: line 5\n" | |||
MinRK
|
r7402 | ] | |
} | |||
MinRK
|
r7739 | ], | |
Min RK
|
r18669 | "source": [ | |
"import time\n", | |||
"tic = time.time()\n", | |||
"line = True\n", | |||
"while True:\n", | |||
" line = bashout.readline()\n", | |||
" if not line:\n", | |||
" break\n", | |||
" sys.stdout.write(\"%.1fs: %s\" %(time.time()-tic, line))\n", | |||
" sys.stdout.flush()\n" | |||
] | |||
}, | |||
{ | |||
"cell_type": "markdown", | |||
"metadata": {}, | |||
"source": [ | |||
"## Configuring the default ScriptMagics" | |||
] | |||
}, | |||
{ | |||
"cell_type": "markdown", | |||
"metadata": {}, | |||
"source": [ | |||
"The list of aliased script magics is configurable.\n", | |||
"\n", | |||
"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:\n", | |||
"\n", | |||
" c.ScriptMagics.scripts = ['R', 'pypy', 'myprogram']\n", | |||
"\n", | |||
"And if any of these programs do not apear on your default PATH, then you would also need to specify their location with:\n", | |||
"\n", | |||
" c.ScriptMagics.script_paths = {'myprogram': '/opt/path/to/myprogram'}" | |||
] | |||
MinRK
|
r7402 | } | |
Min RK
|
r18669 | ], | |
"metadata": {}, | |||
"nbformat": 4, | |||
"nbformat_minor": 0 | |||
MinRK
|
r7402 | } |