diff --git a/nodes/ceph.py b/nodes/ceph.py
index e69de29..a2036b2 100644
--- a/nodes/ceph.py
+++ b/nodes/ceph.py
@@ -0,0 +1,114 @@
+""" Collect data about ceph nodes"""
+import json
+
+import sh
+from connection import Connection
+
+
+def discover_ceph_node():
+    """ Return list of ceph's nodes ips """
+    
+    ips = {}
+    osd_list = get_osds_list()
+    osd_ips = get_osds_ips(osd_list)
+    mon_ips = get_mons_or_mds_ips("mon")
+    mds_ips = get_mons_or_mds_ips("mds")
+    for ip in osd_ips:
+        url = "ssh://%s" % ip
+        if url in ips:
+            ips[url].add("ceph-osd")
+        else:
+            ips[url] = ("ceph-osd")
+    for ip in mon_ips:
+        url = "ssh://%s" % ip
+        if url in ips:
+            ips[url].add("ceph-mon")
+        else:
+            ips[url] = ("ceph-mon")
+    for ip in mds_ips:
+        url = "ssh://%s" % ip
+        if url in ips:
+            ips[url].add("ceph-mds")
+        else:
+            ips[url] = ("ceph-mds")
+
+    res = []
+    for url, roles in ips:
+        item = Connection()
+        item.url = url
+        item.roles = list(roles)
+        res.append(item)
+
+    return res
+
+
+# internal services
+
+
+class CephException(Exception):
+    """ Exceptions from ceph call"""
+    pass
+
+class ParameterException(Exception):
+    """ Bad parameter in function"""
+    pass
+
+
+def get_osds_list():
+    """ Get list of osds id"""
+    try:
+        res = sh.ceph.osd.ls()
+        osd_list = [osd_id
+                    for osd_id in res.split("\n") if osd_id != '']
+        return osd_list
+    except sh.CommandNotFound:
+        raise CephException("Ceph command not found")
+    except:
+        raise CephException("Ceph command 'osd ls' execution error")
+
+
+def get_mons_or_mds_ips(who):
+    """ Return mon ip list
+        :param who - "mon" or "mds" """
+    try:
+        ips = set()
+        if who == "mon":
+            res = sh.ceph.mon.dump()
+        elif who == "mds":
+            res = sh.ceph.mds.dump()
+        else:
+            raise ParameterException("'%s' in get_mons_or_mds_ips instead of mon/mds" % who)
+
+        line_res = res.split("\n")
+        for line in line_res:
+            fields = line.split()
+            if len(fields) > 2 and who in fields[2]:
+                ips.add(fields[1].split(":")[0])
+
+        return ips
+
+    except sh.CommandNotFound:
+        raise CephException("Ceph command not found")
+    except ParameterException as e:
+        raise e
+    except:
+        mes = "Ceph command '%s dump' execution error" % who
+        raise CephException(mes)
+
+
+def get_osds_ips(osd_list):
+    """ Get osd's ips 
+        :param osd_list - list of osd names from osd ls command"""
+    try:
+        ips = set()
+        for osd_id in osd_list:
+            res = sh.ceph.osd.find(osd_id)
+            ip = json.loads(str(res))["ip"]
+            ips.add(ip.split(":")[0])
+        return ips
+
+    except sh.CommandNotFound:
+        raise CephException("Ceph command not found")
+    except:
+        raise CephException("Ceph command 'osd find' execution error")
+
diff --git a/nodes/connection.py b/nodes/connection.py
new file mode 100644
index 0000000..d565ab5
--- /dev/null
+++ b/nodes/connection.py
@@ -0,0 +1,4 @@
+
+
+class Connection(object):
+    pass
diff --git a/nodes/sh.py b/nodes/sh.py
new file mode 100644
index 0000000..fb0f5fe
--- /dev/null
+++ b/nodes/sh.py
@@ -0,0 +1,2352 @@
+"""
+http://amoffat.github.io/sh/
+"""
+#===============================================================================
+# Copyright (C) 2011-2015 by Andrew Moffat
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#===============================================================================
+
+
+__version__ = "1.11"
+__project_url__ = "https://github.com/amoffat/sh"
+
+
+
+import platform
+
+if "windows" in platform.system().lower():
+    raise ImportError("sh %s is currently only supported on linux and osx. \
+please install pbs 0.110 (http://pypi.python.org/pypi/pbs) for windows \
+support." % __version__)
+
+
+import sys
+IS_PY3 = sys.version_info[0] == 3
+
+import traceback
+import os
+import re
+from glob import glob as original_glob
+import time
+from types import ModuleType
+from functools import partial
+import inspect
+from contextlib import contextmanager
+
+from locale import getpreferredencoding
+DEFAULT_ENCODING = getpreferredencoding() or "UTF-8"
+
+
+if IS_PY3:
+    from io import StringIO
+    from io import BytesIO as cStringIO
+    from queue import Queue, Empty
+
+    # for some reason, python 3.1 removed the builtin "callable", wtf
+    if not hasattr(__builtins__, "callable"):
+        def callable(ob):
+            return hasattr(ob, "__call__")
+else:
+    from StringIO import StringIO
+    from cStringIO import OutputType as cStringIO
+    from Queue import Queue, Empty
+
+IS_OSX = platform.system() == "Darwin"
+THIS_DIR = os.path.dirname(os.path.realpath(__file__))
+SH_LOGGER_NAME = "sh"
+
+
+import errno
+import warnings
+
+import pty
+import termios
+import signal
+import gc
+import select
+import threading
+import tty
+import fcntl
+import struct
+import resource
+from collections import deque
+import logging
+import weakref
+
+
+# TODO remove with contexts in next version
+def with_context_warning():
+    warnings.warn("""
+with contexts are deprecated because they are not thread safe.  they will be \
+removed in the next version.  use subcommands instead \
+http://amoffat.github.io/sh/#sub-commands. see \
+https://github.com/amoffat/sh/issues/195
+""".strip(), stacklevel=3)
+
+
+
+if IS_PY3:
+    raw_input = input
+    unicode = str
+    basestring = str
+
+
+_unicode_methods = set(dir(unicode()))
+
+
+def encode_to_py3bytes_or_py2str(s):
+    """ takes anything and attempts to return a py2 string or py3 bytes.  this
+    is typically used when creating command + arguments to be executed via
+    os.exec* """
+
+    fallback_encoding = "utf8"
+
+    if IS_PY3:
+        # if we're already bytes, do nothing
+        if isinstance(s, bytes):
+            pass
+        else:
+            s = str(s)
+            try:
+                s = bytes(s, DEFAULT_ENCODING)
+            except UnicodeEncodeError:
+                s = bytes(s, fallback_encoding)
+    else:
+        # attempt to convert the thing to unicode from the system's encoding
+        try:
+            s = unicode(s, DEFAULT_ENCODING)
+        # if the thing is already unicode, or it's a number, it can't be
+        # coerced to unicode with an encoding argument, but if we leave out
+        # the encoding argument, it will convert it to a string, then to unicode
+        except TypeError:
+            s = unicode(s)
+
+        # now that we have guaranteed unicode, encode to our system encoding,
+        # but attempt to fall back to something
+        try:
+            s = s.encode(DEFAULT_ENCODING)
+        except:
+            s = s.encode(fallback_encoding)
+    return s
+
+
+class ErrorReturnCode(Exception):
+    """ base class for all exceptions as a result of a command's exit status
+    being deemed an error.  this base class is dynamically subclassed into
+    derived classes with the format: ErrorReturnCode_NNN where NNN is the exit
+    code number.  the reason for this is it reduces boiler plate code when
+    testing error return codes:
+    
+        try:
+            some_cmd()
+        except ErrorReturnCode_12:
+            print("couldn't do X")
+            
+    vs:
+        try:
+            some_cmd()
+        except ErrorReturnCode as e:
+            if e.exit_code == 12:
+                print("couldn't do X")
+    
+    it's not much of a savings, but i believe it makes the code easier to read """
+
+    truncate_cap = 750
+
+    def __init__(self, full_cmd, stdout, stderr):
+        self.full_cmd = full_cmd
+        self.stdout = stdout
+        self.stderr = stderr
+
+
+        if self.stdout is None:
+            exc_stdout = "<redirected>"
+        else:
+            exc_stdout = self.stdout[:self.truncate_cap]
+            out_delta = len(self.stdout) - len(exc_stdout)
+            if out_delta:
+                exc_stdout += ("... (%d more, please see e.stdout)" % out_delta).encode()
+
+        if self.stderr is None:
+            exc_stderr = "<redirected>"
+        else:
+            exc_stderr = self.stderr[:self.truncate_cap]
+            err_delta = len(self.stderr) - len(exc_stderr)
+            if err_delta:
+                exc_stderr += ("... (%d more, please see e.stderr)" % err_delta).encode()
+
+        msg = "\n\n  RAN: %r\n\n  STDOUT:\n%s\n\n  STDERR:\n%s" % \
+            (full_cmd, exc_stdout.decode(DEFAULT_ENCODING, "replace"),
+             exc_stderr.decode(DEFAULT_ENCODING, "replace"))
+        super(ErrorReturnCode, self).__init__(msg)
+
+
+class SignalException(ErrorReturnCode): pass
+class TimeoutException(Exception):
+    """ the exception thrown when a command is killed because a specified
+    timeout (via _timeout) was hit """
+    def __init__(self, exit_code):
+        self.exit_code = exit_code
+        super(Exception, self).__init__()
+
+SIGNALS_THAT_SHOULD_THROW_EXCEPTION = (
+    signal.SIGABRT,
+    signal.SIGBUS,
+    signal.SIGFPE,
+    signal.SIGILL,
+    signal.SIGINT,
+    signal.SIGKILL,
+    signal.SIGPIPE,
+    signal.SIGQUIT,
+    signal.SIGSEGV,
+    signal.SIGTERM,
+    signal.SIGSYS,
+)
+
+
+# we subclass AttributeError because:
+# https://github.com/ipython/ipython/issues/2577
+# https://github.com/amoffat/sh/issues/97#issuecomment-10610629
+class CommandNotFound(AttributeError): pass
+
+
+
+
+rc_exc_regex = re.compile("(ErrorReturnCode|SignalException)_((\d+)|SIG\w+)")
+rc_exc_cache = {}
+
+
+def get_exc_from_name(name):
+    """ takes an exception name, like:
+
+        ErrorReturnCode_1
+        SignalException_9
+        SignalException_SIGHUP
+
+    and returns the corresponding exception.  this is primarily used for
+    importing exceptions from sh into user code, for instance, to capture those
+    exceptions """
+
+    exc = None
+    try:
+        return rc_exc_cache[name]
+    except KeyError:
+        m = rc_exc_regex.match(name)
+        if m:
+            base = m.group(1)
+            rc_or_sig_name = m.group(2)
+
+            if base == "SignalException":
+                try:
+                    rc = -int(rc_or_sig_name)
+                except ValueError:
+                    rc = -getattr(signal, rc_or_sig_name)
+            else:
+                rc = int(rc_or_sig_name)
+
+            exc = get_rc_exc(rc)
+    return exc
+
+
+def get_rc_exc(rc_or_sig_name):
+    """ takes a exit code, signal number, or signal name, and produces an
+    exception that corresponds to that return code.  positive return codes yield
+    ErrorReturnCode exception, negative return codes yield SignalException
+
+    we also cache the generated exception so that only one signal of that type
+    exists, preserving identity """
+
+    try:
+        rc = int(rc_or_sig_name)
+    except ValueError:
+        rc = -getattr(signal, rc_or_sig_name)
+
+    try:
+        return rc_exc_cache[rc]
+    except KeyError:
+        pass
+
+    if rc > 0:
+        name = "ErrorReturnCode_%d" % rc
+        base = ErrorReturnCode
+    else:
+        name = "SignalException_%d" % abs(rc)
+        base = SignalException
+
+    exc = type(name, (base,), {"exit_code": rc})
+    rc_exc_cache[rc] = exc
+    return exc
+
+
+
+
+def which(program):
+    def is_exe(fpath):
+        return (os.path.exists(fpath) and
+                os.access(fpath, os.X_OK) and
+                os.path.isfile(os.path.realpath(fpath)))
+
+    fpath, fname = os.path.split(program)
+    if fpath:
+        if is_exe(program):
+            return program
+    else:
+        if "PATH" not in os.environ:
+            return None
+        for path in os.environ["PATH"].split(os.pathsep):
+            exe_file = os.path.join(path, program)
+            if is_exe(exe_file):
+                return exe_file
+
+    return None
+
+def resolve_program(program):
+    path = which(program)
+    if not path:
+        # our actual command might have a dash in it, but we can't call
+        # that from python (we have to use underscores), so we'll check
+        # if a dash version of our underscore command exists and use that
+        # if it does
+        if "_" in program:
+            path = which(program.replace("_", "-"))
+        if not path:
+            return None
+    return path
+
+
+# we add this thin wrapper to glob.glob because of a specific edge case where
+# glob does not expand to anything.  for example, if you try to do
+# glob.glob("*.py") and there are no *.py files in the directory, glob.glob
+# returns an empty list.  this empty list gets passed to the command, and
+# then the command fails with a misleading error message.  this thin wrapper
+# ensures that if there is no expansion, we pass in the original argument,
+# so that when the command fails, the error message is clearer
+def glob(arg):
+    return original_glob(arg) or arg
+
+
+
+class Logger(object):
+    """ provides a memory-inexpensive logger.  a gotcha about python's builtin
+    logger is that logger objects are never garbage collected.  if you create a
+    thousand loggers with unique names, they'll sit there in memory until your
+    script is done.  with sh, it's easy to create loggers with unique names if
+    we want our loggers to include our command arguments.  for example, these
+    are all unique loggers:
+        
+            ls -l
+            ls -l /tmp
+            ls /tmp
+
+    so instead of creating unique loggers, and without sacrificing logging
+    output, we use this class, which maintains as part of its state, the logging
+    "context", which will be the very unique name.  this allows us to get a
+    logger with a very general name, eg: "command", and have a unique name
+    appended to it via the context, eg: "ls -l /tmp" """
+    def __init__(self, name, context=None):
+        self.name = name
+        if context:
+            context = context.replace("%", "%%")
+        self.context = context 
+        self.log = logging.getLogger("%s.%s" % (SH_LOGGER_NAME, name))
+
+    def _format_msg(self, msg, *args):
+        if self.context:
+            msg = "%s: %s" % (self.context, msg)
+        return msg % args
+
+    def get_child(self, name, context):
+        new_name = self.name + "." + name
+        new_context = self.context + "." + context
+        l = Logger(new_name, new_context)
+        return l
+
+    def info(self, msg, *args):
+        self.log.info(self._format_msg(msg, *args))
+
+    def debug(self, msg, *args):
+        self.log.debug(self._format_msg(msg, *args))
+
+    def error(self, msg, *args):
+        self.log.error(self._format_msg(msg, *args))
+
+    def exception(self, msg, *args):
+        self.log.exception(self._format_msg(msg, *args))
+
+
+def friendly_truncate(s, max_len):
+    if len(s) > max_len:
+        s = "%s...(%d more)" % (s[:max_len], len(s) - max_len)
+    return s
+
+
+class RunningCommand(object):
+    """ this represents an executing Command object.  it is returned as the
+    result of __call__() being executed on a Command instance.  this creates a
+    reference to a OProc instance, which is a low-level wrapper around the
+    process that was exec'd
+
+    this is the class that gets manipulated the most by user code, and so it
+    implements various convenience methods and logical mechanisms for the
+    underlying process.  for example, if a user tries to access a
+    backgrounded-process's stdout/err, the RunningCommand object is smart enough
+    to know to wait() on the process to finish first.  and when the process
+    finishes, RunningCommand is smart enough to translate exit codes to
+    exceptions. """
+
+    def __init__(self, cmd, call_args, stdin, stdout, stderr):
+        # self.ran is used for auditing what actually ran.  for example, in
+        # exceptions, or if you just want to know what was ran after the
+        # command ran
+        if IS_PY3:
+            self.ran = " ".join([arg.decode(DEFAULT_ENCODING, "ignore") for arg in cmd])
+        else:
+            self.ran = " ".join(cmd)
+
+
+        friendly_cmd = friendly_truncate(self.ran, 20)
+        friendly_call_args = friendly_truncate(str(call_args), 20)
+
+        # we're setting up the logger string here, instead of __repr__ because
+        # we reserve __repr__ to behave as if it was evaluating the child
+        # process's output
+        logger_str = "<Command %r call_args %s>" % (friendly_cmd,
+                friendly_call_args)
+
+        self.log = Logger("command", logger_str)
+        self.call_args = call_args
+        self.cmd = cmd
+
+        self.process = None
+        self._process_completed = False
+        should_wait = True
+        spawn_process = True
+
+
+        # with contexts shouldn't run at all yet, they prepend
+        # to every command in the context
+        if call_args["with"]:
+            spawn_process = False
+            Command._prepend_stack.append(self)
+
+
+        if call_args["piped"] or call_args["iter"] or call_args["iter_noblock"]:
+            should_wait = False
+
+        # we're running in the background, return self and let us lazily
+        # evaluate
+        if call_args["bg"]:
+            should_wait = False
+
+        # redirection
+        if call_args["err_to_out"]:
+            stderr = OProc.STDOUT
+
+
+        # set up which stream should write to the pipe
+        # TODO, make pipe None by default and limit the size of the Queue
+        # in oproc.OProc
+        pipe = OProc.STDOUT
+        if call_args["iter"] == "out" or call_args["iter"] is True:
+            pipe = OProc.STDOUT
+        elif call_args["iter"] == "err":
+            pipe = OProc.STDERR
+
+        if call_args["iter_noblock"] == "out" or call_args["iter_noblock"] is True:
+            pipe = OProc.STDOUT
+        elif call_args["iter_noblock"] == "err":
+            pipe = OProc.STDERR
+
+
+        # there's currently only one case where we wouldn't spawn a child
+        # process, and that's if we're using a with-context with our command
+        if spawn_process:
+            self.log.info("starting process")
+            self.process = OProc(self.log, cmd, stdin, stdout, stderr,
+                    self.call_args, pipe)
+
+            if should_wait:
+                self.wait()
+
+
+    def wait(self):
+        if not self._process_completed:
+            self._process_completed = True
+
+            exit_code = self.process.wait()
+            if self.process.timed_out:
+                # if we timed out, our exit code represents a signal, which is
+                # negative, so let's make it positive to store in our
+                # TimeoutException
+                raise TimeoutException(-exit_code)
+            else:
+                self.handle_command_exit_code(exit_code)
+
+            # https://github.com/amoffat/sh/issues/185
+            if self.call_args["done"]:
+                self.call_args["done"](self)
+
+        return self
+
+
+    def handle_command_exit_code(self, code):
+        """ here we determine if we had an exception, or an error code that we
+        weren't expecting to see.  if we did, we create and raise an exception
+        """
+        if (code not in self.call_args["ok_code"] and (code > 0 or -code in
+            SIGNALS_THAT_SHOULD_THROW_EXCEPTION)):
+            exc = get_rc_exc(code)
+            raise exc(self.ran, self.process.stdout, self.process.stderr)
+
+
+
+    @property
+    def stdout(self):
+        self.wait()
+        return self.process.stdout
+
+    @property
+    def stderr(self):
+        self.wait()
+        return self.process.stderr
+
+    @property
+    def exit_code(self):
+        self.wait()
+        return self.process.exit_code
+
+    @property
+    def pid(self):
+        return self.process.pid
+
+    def __len__(self):
+        return len(str(self))
+
+    def __enter__(self):
+        """ we don't actually do anything here because anything that should have
+        been done would have been done in the Command.__call__ call.
+        essentially all that has to happen is the comand be pushed on the
+        prepend stack. """
+        with_context_warning()
+
+    def __iter__(self):
+        return self
+
+    def next(self):
+        """ allow us to iterate over the output of our command """
+
+        # we do this because if get blocks, we can't catch a KeyboardInterrupt
+        # so the slight timeout allows for that.
+        while True:
+            try:
+                chunk = self.process._pipe_queue.get(True, 0.001)
+            except Empty:
+                if self.call_args["iter_noblock"]:
+                    return errno.EWOULDBLOCK
+            else:
+                if chunk is None:
+                    self.wait()
+                    raise StopIteration()
+                try:
+                    return chunk.decode(self.call_args["encoding"],
+                        self.call_args["decode_errors"])
+                except UnicodeDecodeError:
+                    return chunk
+
+    # python 3
+    __next__ = next
+
+    def __exit__(self, typ, value, traceback):
+        if self.call_args["with"] and Command._prepend_stack:
+            Command._prepend_stack.pop()
+
+    def __str__(self):
+        """ in python3, should return unicode.  in python2, should return a
+        string of bytes """
+        if IS_PY3:
+            return self.__unicode__()
+        else:
+            return unicode(self).encode(self.call_args["encoding"])
+
+    def __unicode__(self):
+        """ a magic method defined for python2.  calling unicode() on a
+        RunningCommand object will call this """
+        if self.process and self.stdout:
+            return self.stdout.decode(self.call_args["encoding"],
+                self.call_args["decode_errors"])
+        elif IS_PY3:
+            return ""
+        else:
+            return unicode("")
+
+    def __eq__(self, other):
+        return unicode(self) == unicode(other)
+    __hash__ = None  # Avoid DeprecationWarning in Python < 3
+
+    def __contains__(self, item):
+        return item in str(self)
+
+    def __getattr__(self, p):
+        # let these three attributes pass through to the OProc object
+        if p in ("signal", "terminate", "kill"):
+            if self.process:
+                return getattr(self.process, p)
+            else:
+                raise AttributeError
+
+        # see if strings have what we're looking for.  we're looking at the
+        # method names explicitly because we don't want to evaluate self unless
+        # we absolutely have to, the reason being, in python2, hasattr swallows
+        # exceptions, and if we try to run hasattr on a command that failed and
+        # is being run with _iter=True, the command will be evaluated, throw an
+        # exception, but hasattr will discard it
+        if p in _unicode_methods:
+            return getattr(unicode(self), p)
+
+        raise AttributeError
+
+    def __repr__(self):
+        """ in python3, should return unicode.  in python2, should return a
+        string of bytes """
+        try:
+            return str(self)
+        except UnicodeDecodeError:
+            if self.process:
+                if self.stdout:
+                    return repr(self.stdout)
+            return repr("")
+
+    def __long__(self):
+        return long(str(self).strip())
+
+    def __float__(self):
+        return float(str(self).strip())
+
+    def __int__(self):
+        return int(str(self).strip())
+
+
+
+def output_redirect_is_filename(out):
+    return out \
+        and not callable(out) \
+        and not hasattr(out, "write") \
+        and not isinstance(out, (cStringIO, StringIO))
+
+
+
+
+
+
+class Command(object):
+    """ represents an un-run system program, like "ls" or "cd".  because it
+    represents the program itself (and not a running instance of it), it should
+    hold very little state.  in fact, the only state it does hold is baked
+    arguments.
+    
+    when a Command object is called, the result that is returned is a
+    RunningCommand object, which represents the Command put into an execution
+    state. """
+    _prepend_stack = []
+
+    _call_args = {
+        # currently unsupported
+        #"fg": False, # run command in foreground
+
+        # run a command in the background.  commands run in the background
+        # ignore SIGHUP and do not automatically exit when the parent process
+        # ends
+        "bg": False,
+
+        "with": False, # prepend the command to every command after it
+        "in": None,
+        "out": None, # redirect STDOUT
+        "err": None, # redirect STDERR
+        "err_to_out": None, # redirect STDERR to STDOUT
+
+        # stdin buffer size
+        # 1 for line, 0 for unbuffered, any other number for that amount
+        "in_bufsize": 0,
+        # stdout buffer size, same values as above
+        "out_bufsize": 1,
+        "err_bufsize": 1,
+
+        # this is how big the output buffers will be for stdout and stderr.
+        # this is essentially how much output they will store from the process.
+        # we use a deque, so if it overflows past this amount, the first items
+        # get pushed off as each new item gets added.
+        #
+        # NOTICE
+        # this is not a *BYTE* size, this is a *CHUNK* size...meaning, that if
+        # you're buffering out/err at 1024 bytes, the internal buffer size will
+        # be "internal_bufsize" CHUNKS of 1024 bytes
+        "internal_bufsize": 3 * 1024 ** 2,
+
+        "env": None,
+        "piped": None,
+        "iter": None,
+        "iter_noblock": None,
+        "ok_code": 0,
+        "cwd": None,
+
+        # the separator delimiting between a long-argument's name and its value
+        # for example, --arg=derp, '=' is the long_sep
+        "long_sep": "=",
+
+        # this is for programs that expect their input to be from a terminal.
+        # ssh is one of those programs
+        "tty_in": False,
+        "tty_out": True,
+
+        "encoding": DEFAULT_ENCODING,
+        "decode_errors": "strict",
+
+        # how long the process should run before it is auto-killed
+        "timeout": 0,
+        "timeout_signal": signal.SIGKILL,
+
+        # TODO write some docs on "long-running processes"
+        # these control whether or not stdout/err will get aggregated together
+        # as the process runs.  this has memory usage implications, so sometimes
+        # with long-running processes with a lot of data, it makes sense to
+        # set these to true
+        "no_out": False,
+        "no_err": False,
+        "no_pipe": False,
+
+        # if any redirection is used for stdout or stderr, internal buffering
+        # of that data is not stored.  this forces it to be stored, as if
+        # the output is being T'd to both the redirected destination and our
+        # internal buffers
+        "tee": None,
+
+        # will be called when a process terminates without exception.  this
+        # option also puts the command in the background, since it doesn't make
+        # sense to have an un-backgrounded command with a done callback
+        "done": None,
+
+        # a tuple (rows, columns) of the desired size of both the stdout and
+        # stdin ttys, if ttys are being used
+        "tty_size": (20, 80),
+    }
+
+    # these are arguments that cannot be called together, because they wouldn't
+    # make any sense
+    _incompatible_call_args = (
+        #("fg", "bg", "Command can't be run in the foreground and background"),
+        ("err", "err_to_out", "Stderr is already being redirected"),
+        ("piped", "iter", "You cannot iterate when this command is being piped"),
+        ("piped", "no_pipe", "Using a pipe doesn't make sense if you've \
+disabled the pipe"),
+        ("no_out", "iter", "You cannot iterate over output if there is no \
+output"),
+    )
+
+
+    # this method exists because of the need to have some way of letting
+    # manual object instantiation not perform the underscore-to-dash command
+    # conversion that resolve_program uses.
+    #
+    # there are 2 ways to create a Command object.  using sh.Command(<program>)
+    # or by using sh.<program>.  the method fed into sh.Command must be taken
+    # literally, and so no underscore-dash conversion is performed.  the one
+    # for sh.<program> must do the underscore-dash converesion, because we
+    # can't type dashes in method names
+    @classmethod
+    def _create(cls, program, **default_kwargs):
+        path = resolve_program(program)
+        if not path:
+            raise CommandNotFound(program)
+
+        cmd = cls(path)
+        if default_kwargs:
+            cmd = cmd.bake(**default_kwargs)
+
+        return cmd
+
+
+    def __init__(self, path):
+        found = which(path)
+        if not found:
+            raise CommandNotFound(path)
+
+        self._path = encode_to_py3bytes_or_py2str(found) 
+
+        self._partial = False
+        self._partial_baked_args = []
+        self._partial_call_args = {}
+
+        # bugfix for functools.wraps.  issue #121
+        self.__name__ = str(self)
+
+
+    def __getattribute__(self, name):
+        # convenience
+        getattr = partial(object.__getattribute__, self)
+
+        if name.startswith("_"):
+            return getattr(name)
+        if name == "bake":
+            return getattr("bake")
+        if name.endswith("_"):
+            name = name[:-1]
+
+        return getattr("bake")(name)
+
+
+    @staticmethod
+    def _extract_call_args(kwargs, to_override={}):
+        kwargs = kwargs.copy()
+        call_args = {}
+        for parg, default in Command._call_args.items():
+            key = "_" + parg
+
+            if key in kwargs:
+                call_args[parg] = kwargs[key]
+                del kwargs[key]
+            elif parg in to_override:
+                call_args[parg] = to_override[parg]
+
+        # test for incompatible call args
+        s1 = set(call_args.keys())
+        for args in Command._incompatible_call_args:
+            args = list(args)
+            error = args.pop()
+
+            if s1.issuperset(args):
+                raise TypeError("Invalid special arguments %r: %s" % (args, error))
+
+        return call_args, kwargs
+
+
+    def _aggregate_keywords(self, keywords, sep, raw=False):
+        processed = []
+        for k, v in keywords.items():
+            # we're passing a short arg as a kwarg, example:
+            # cut(d="\t")
+            if len(k) == 1:
+                if v is not False:
+                    processed.append(encode_to_py3bytes_or_py2str("-" + k))
+                    if v is not True:
+                        processed.append(encode_to_py3bytes_or_py2str(v))
+
+            # we're doing a long arg
+            else:
+                if not raw:
+                    k = k.replace("_", "-")
+
+                if v is True:
+                    processed.append(encode_to_py3bytes_or_py2str("--" + k))
+                elif v is False:
+                    pass
+                else:
+                    arg = encode_to_py3bytes_or_py2str("--%s%s%s" % (k, sep, v))
+                    processed.append(arg)
+        return processed
+
+
+    def _compile_args(self, args, kwargs, sep):
+        processed_args = []
+
+        # aggregate positional args
+        for arg in args:
+            if isinstance(arg, (list, tuple)):
+                if not arg:
+                    warnings.warn("Empty list passed as an argument to %r. \
+If you're using glob.glob(), please use sh.glob() instead." % self._path, stacklevel=3)
+                for sub_arg in arg:
+                    processed_args.append(encode_to_py3bytes_or_py2str(sub_arg))
+            elif isinstance(arg, dict):
+                processed_args += self._aggregate_keywords(arg, sep, raw=True)
+            else:
+                processed_args.append(encode_to_py3bytes_or_py2str(arg))
+
+        # aggregate the keyword arguments
+        processed_args += self._aggregate_keywords(kwargs, sep)
+
+        return processed_args
+
+
+    # TODO needs documentation
+    def bake(self, *args, **kwargs):
+        fn = Command(self._path)
+        fn._partial = True
+
+        call_args, kwargs = self._extract_call_args(kwargs)
+
+        pruned_call_args = call_args
+        for k, v in Command._call_args.items():
+            try:
+                if pruned_call_args[k] == v:
+                    del pruned_call_args[k]
+            except KeyError:
+                continue
+
+        fn._partial_call_args.update(self._partial_call_args)
+        fn._partial_call_args.update(pruned_call_args)
+        fn._partial_baked_args.extend(self._partial_baked_args)
+        sep = pruned_call_args.get("long_sep", self._call_args["long_sep"])
+        fn._partial_baked_args.extend(self._compile_args(args, kwargs, sep))
+        return fn
+
+    def __str__(self):
+        """ in python3, should return unicode.  in python2, should return a
+        string of bytes """
+        if IS_PY3:
+            return self.__unicode__()
+        else:
+            return self.__unicode__().encode(DEFAULT_ENCODING)
+
+
+    def __eq__(self, other):
+        try:
+            return str(self) == str(other)
+        except:
+            return False
+    __hash__ = None  # Avoid DeprecationWarning in Python < 3
+
+
+    def __repr__(self):
+        """ in python3, should return unicode.  in python2, should return a
+        string of bytes """
+        return "<Command %r>" % str(self)
+
+
+    def __unicode__(self):
+        """ a magic method defined for python2.  calling unicode() on a
+        self will call this """
+        baked_args = " ".join(item.decode(DEFAULT_ENCODING) for item in self._partial_baked_args)
+        if baked_args:
+            baked_args = " " + baked_args
+        return self._path.decode(DEFAULT_ENCODING) + baked_args
+
+    def __enter__(self):
+        with_context_warning()
+        self(_with=True)
+
+    def __exit__(self, typ, value, traceback):
+        Command._prepend_stack.pop()
+
+
+    def __call__(self, *args, **kwargs):
+        kwargs = kwargs.copy()
+        args = list(args)
+
+        cmd = []
+
+        # aggregate any 'with' contexts
+        call_args = Command._call_args.copy()
+        for prepend in self._prepend_stack:
+            # don't pass the 'with' call arg
+            pcall_args = prepend.call_args.copy()
+            try:
+                del pcall_args["with"]
+            except:
+                pass
+
+            call_args.update(pcall_args)
+            cmd.extend(prepend.cmd)
+
+        cmd.append(self._path)
+
+        # here we extract the special kwargs and override any
+        # special kwargs from the possibly baked command
+        tmp_call_args, kwargs = self._extract_call_args(kwargs, self._partial_call_args)
+        call_args.update(tmp_call_args)
+
+        if not getattr(call_args["ok_code"], "__iter__", None):
+            call_args["ok_code"] = [call_args["ok_code"]]
+
+
+        if call_args["done"]:
+            call_args["bg"] = True
+
+        # check if we're piping via composition
+        stdin = call_args["in"]
+        if args:
+            first_arg = args.pop(0)
+            if isinstance(first_arg, RunningCommand):
+                # it makes sense that if the input pipe of a command is running
+                # in the background, then this command should run in the
+                # background as well
+                if first_arg.call_args["bg"]:
+                    call_args["bg"] = True
+
+                if first_arg.call_args["piped"] == "direct":
+                    stdin = first_arg.process
+                else:
+                    stdin = first_arg.process._pipe_queue
+
+            else:
+                args.insert(0, first_arg)
+
+        processed_args = self._compile_args(args, kwargs, call_args["long_sep"])
+
+        # makes sure our arguments are broken up correctly
+        split_args = self._partial_baked_args + processed_args
+
+        final_args = split_args
+
+        cmd.extend(final_args)
+
+
+        # stdout redirection
+        stdout = call_args["out"]
+        if output_redirect_is_filename(stdout):
+            stdout = open(str(stdout), "wb")
+
+        # stderr redirection
+        stderr = call_args["err"]
+        if output_redirect_is_filename(stderr):
+            stderr = open(str(stderr), "wb")
+
+
+        return RunningCommand(cmd, call_args, stdin, stdout, stderr)
+
+
+
+
+def _start_daemon_thread(fn, *args):
+    thrd = threading.Thread(target=fn, args=args)
+    thrd.daemon = True
+    thrd.start()
+    return thrd
+
+
+def setwinsize(fd, rows_cols):
+    """ set the terminal size of a tty file descriptor.  borrowed logic
+    from pexpect.py """
+    rows, cols = rows_cols
+    TIOCSWINSZ = getattr(termios, 'TIOCSWINSZ', -2146929561)
+
+    s = struct.pack('HHHH', rows, cols, 0, 0)
+    fcntl.ioctl(fd, TIOCSWINSZ, s)
+
+def construct_streamreader_callback(process, handler):
+    """ here we're constructing a closure for our streamreader callback.  this
+    is used in the case that we pass a callback into _out or _err, meaning we
+    want to our callback to handle each bit of output
+
+    we construct the closure based on how many arguments it takes.  the reason
+    for this is to make it as easy as possible for people to use, without
+    limiting them.  a new user will assume the callback takes 1 argument (the
+    data).  as they get more advanced, they may want to terminate the process,
+    or pass some stdin back, and will realize that they can pass a callback of
+    more args """
+
+
+    # implied arg refers to the "self" that methods will pass in.  we need to
+    # account for this implied arg when figuring out what function the user
+    # passed in based on number of args
+    implied_arg = 0
+
+    partial_args = 0
+    handler_to_inspect = handler
+
+    if isinstance(handler, partial):
+        partial_args = len(handler.args)
+        handler_to_inspect = handler.func
+
+    if inspect.ismethod(handler_to_inspect):
+        implied_arg = 1
+        num_args = len(inspect.getargspec(handler_to_inspect).args)
+
+    else:
+        if inspect.isfunction(handler_to_inspect):
+            num_args = len(inspect.getargspec(handler_to_inspect).args)
+
+        # is an object instance with __call__ method
+        else:
+            implied_arg = 1
+            num_args = len(inspect.getargspec(handler_to_inspect.__call__).args)
+
+
+    net_args = num_args - implied_arg - partial_args
+
+    handler_args = ()
+
+    # just the chunk
+    if net_args == 1:
+        handler_args = ()
+
+    # chunk, stdin
+    if net_args == 2:
+        handler_args = (process.stdin,)
+
+    # chunk, stdin, process
+    elif net_args == 3:
+        # notice we're only storing a weakref, to prevent cyclic references
+        # (where the process holds a streamreader, and a streamreader holds a
+        # handler-closure with a reference to the process
+        handler_args = (process.stdin, weakref.ref(process))
+
+    def fn(chunk):
+        # this is pretty ugly, but we're evaluating the process at call-time,
+        # because it's a weakref
+        args = handler_args
+        if len(args) == 2:
+            args = (handler_args[0], handler_args[1]())
+        return handler(chunk, *args)
+
+    return fn
+
+
+
+def handle_process_exit_code(exit_code):
+    """ this should only ever be called once for each child process """
+    # if we exited from a signal, let our exit code reflect that
+    if os.WIFSIGNALED(exit_code):
+        return -os.WTERMSIG(exit_code)
+    # otherwise just give us a normal exit code
+    elif os.WIFEXITED(exit_code):
+        return os.WEXITSTATUS(exit_code)
+    else:
+        raise RuntimeError("Unknown child exit status!")
+
+
+
+
+class OProc(object):
+    """ this class is instantiated by RunningCommand for a command to be exec'd.
+    it handles all the nasty business involved with correctly setting up the
+    input/output to the child process.  it gets its name for subprocess.Popen
+    (process open) but we're calling ours OProc (open process) """
+
+    _default_window_size = (24, 80)
+
+    # used in redirecting
+    STDOUT = -1
+    STDERR = -2
+
+    def __init__(self, parent_log, cmd, stdin, stdout, stderr, call_args, pipe):
+        """
+            cmd is the full string that will be exec'd.  it includes the program
+            name and all its arguments
+
+            stdin, stdout, stderr are what the child will use for standard
+            input/output/err
+
+            call_args is a mapping of all the special keyword arguments to apply
+            to the child process
+        """
+
+        self.call_args = call_args
+
+        # I had issues with getting 'Input/Output error reading stdin' from dd,
+        # until I set _tty_out=False
+        if self.call_args["piped"] == "direct":
+            self.call_args["tty_out"] = False
+
+        self._single_tty = self.call_args["tty_in"] and self.call_args["tty_out"]
+
+        # this logic is a little convoluted, but basically this top-level
+        # if/else is for consolidating input and output TTYs into a single
+        # TTY.  this is the only way some secure programs like ssh will
+        # output correctly (is if stdout and stdin are both the same TTY)
+        if self._single_tty:
+            self._stdin_fd, self._slave_stdin_fd = pty.openpty()
+
+            self._stdout_fd = self._stdin_fd
+            self._slave_stdout_fd = self._slave_stdin_fd
+
+            self._stderr_fd = self._stdin_fd
+            self._slave_stderr_fd = self._slave_stdin_fd
+
+        # do not consolidate stdin and stdout.  this is the most common use-
+        # case
+        else:
+            # this check here is because we may be doing "direct" piping
+            # (_piped="direct"), and so our stdin might be an instance of
+            # OProc
+            if isinstance(stdin, OProc):
+                self._slave_stdin_fd = stdin._stdout_fd
+                self._stdin_fd = None
+            elif self.call_args["tty_in"]:
+                self._slave_stdin_fd, self._stdin_fd = pty.openpty()
+            # tty_in=False is the default
+            else:
+                self._slave_stdin_fd, self._stdin_fd = os.pipe()
+
+
+            # tty_out=True is the default
+            if self.call_args["tty_out"]:
+                self._stdout_fd, self._slave_stdout_fd = pty.openpty()
+            else:
+                self._stdout_fd, self._slave_stdout_fd = os.pipe()
+
+            # unless STDERR is going to STDOUT, it ALWAYS needs to be a pipe,
+            # and never a PTY.  the reason for this is not totally clear to me,
+            # but it has to do with the fact that if STDERR isn't set as the
+            # CTTY (because STDOUT is), the STDERR buffer won't always flush
+            # by the time the process exits, and the data will be lost.
+            # i've only seen this on OSX.
+            if stderr is not OProc.STDOUT:
+                self._stderr_fd, self._slave_stderr_fd = os.pipe()
+
+
+        # this is a hack, but what we're doing here is intentionally throwing an
+        # OSError exception if our child processes's directory doesn't exist,
+        # but we're doing it BEFORE we fork.  the reason for before the fork is
+        # error handling.  i'm currently too lazy to implement what
+        # subprocess.py did and set up a error pipe to handle exceptions that
+        # happen in the child between fork and exec.  it has only been seen in
+        # the wild for a missing cwd, so we'll handle it here.
+        cwd = self.call_args["cwd"]
+        if cwd is not None and not os.path.exists(cwd):
+            os.chdir(cwd)
+
+
+        gc_enabled = gc.isenabled()
+        if gc_enabled:
+            gc.disable()
+        self.pid = os.fork()
+
+
+        # child
+        if self.pid == 0: # pragma: no cover
+            try:
+                # ignoring SIGHUP lets us persist even after the parent process
+                # exits.  only ignore if we're backgrounded
+                if self.call_args["bg"] is True:
+                    signal.signal(signal.SIGHUP, signal.SIG_IGN)
+
+                # this piece of ugliness is due to a bug where we can lose output
+                # if we do os.close(self._slave_stdout_fd) in the parent after
+                # the child starts writing.
+                # see http://bugs.python.org/issue15898
+                if IS_OSX:
+                    time.sleep(0.01)
+
+                os.setsid()
+
+                if self.call_args["tty_out"]:
+                    # set raw mode, so there isn't any weird translation of
+                    # newlines to \r\n and other oddities.  we're not outputting
+                    # to a terminal anyways
+                    #
+                    # we HAVE to do this here, and not in the parent process,
+                    # because we have to guarantee that this is set before the
+                    # child process is run, and we can't do it twice.
+                    tty.setraw(self._slave_stdout_fd)
+
+
+                # if the parent-side fd for stdin exists, close it.  the case
+                # where it may not exist is if we're using piped="direct"
+                if self._stdin_fd:
+                    os.close(self._stdin_fd)
+
+                if not self._single_tty:
+                    os.close(self._stdout_fd)
+                    if stderr is not OProc.STDOUT:
+                        os.close(self._stderr_fd)
+
+
+                if cwd:
+                    os.chdir(cwd)
+
+                os.dup2(self._slave_stdin_fd, 0)
+                os.dup2(self._slave_stdout_fd, 1)
+
+                # we're not directing stderr to stdout?  then set self._slave_stderr_fd to
+                # fd 2, the common stderr fd
+                if stderr is OProc.STDOUT:
+                    os.dup2(self._slave_stdout_fd, 2)
+                else:
+                    os.dup2(self._slave_stderr_fd, 2)
+
+                # don't inherit file descriptors
+                max_fd = resource.getrlimit(resource.RLIMIT_NOFILE)[0]
+                os.closerange(3, max_fd)
+
+
+                # set our controlling terminal.  tty_out defaults to true
+                if self.call_args["tty_out"]:
+                    tmp_fd = os.open(os.ttyname(1), os.O_RDWR)
+                    os.close(tmp_fd)
+
+
+                if self.call_args["tty_out"]:
+                    setwinsize(1, self.call_args["tty_size"])
+
+                # actually execute the process
+                if self.call_args["env"] is None:
+                    os.execv(cmd[0], cmd)
+                else:
+                    os.execve(cmd[0], cmd, self.call_args["env"])
+
+            # we must ensure that we ALWAYS exit the child process, otherwise
+            # the parent process code will be executed twice on exception
+            # https://github.com/amoffat/sh/issues/202
+            #
+            # if your parent process experiences an exit code 255, it is most
+            # likely that an exception occurred between the fork of the child
+            # and the exec.  this should be reported.
+            finally:
+                os._exit(255)
+
+        # parent
+        else:
+            if gc_enabled:
+                gc.enable()
+
+            # used to determine what exception to raise.  if our process was
+            # killed via a timeout counter, we'll raise something different than
+            # a SIGKILL exception
+            self.timed_out = False
+
+            self.started = time.time()
+            self.cmd = cmd
+
+            # exit code should only be manipulated from within self._wait_lock
+            # to prevent race conditions
+            self.exit_code = None
+
+            self.stdin = stdin or Queue()
+
+            # _pipe_queue is used internally to hand off stdout from one process
+            # to another.  by default, all stdout from a process gets dumped
+            # into this pipe queue, to be consumed in real time (hence the
+            # thread-safe Queue), or at a potentially later time
+            self._pipe_queue = Queue()
+
+            # this is used to prevent a race condition when we're waiting for
+            # a process to end, and the OProc's internal threads are also checking
+            # for the processes's end
+            self._wait_lock = threading.Lock()
+
+            # these are for aggregating the stdout and stderr.  we use a deque
+            # because we don't want to overflow
+            self._stdout = deque(maxlen=self.call_args["internal_bufsize"])
+            self._stderr = deque(maxlen=self.call_args["internal_bufsize"])
+
+            if self.call_args["tty_in"]:
+                setwinsize(self._stdin_fd, self.call_args["tty_size"])
+
+
+            self.log = parent_log.get_child("process", repr(self))
+
+            os.close(self._slave_stdin_fd)
+            if not self._single_tty:
+                os.close(self._slave_stdout_fd)
+                if stderr is not OProc.STDOUT:
+                    os.close(self._slave_stderr_fd)
+
+            self.log.debug("started process")
+
+
+            if self.call_args["tty_in"]:
+                attr = termios.tcgetattr(self._stdin_fd)
+                attr[3] &= ~termios.ECHO
+                termios.tcsetattr(self._stdin_fd, termios.TCSANOW, attr)
+
+            # this represents the connection from a Queue object (or whatever
+            # we're using to feed STDIN) to the process's STDIN fd
+            self._stdin_stream = None
+            if not isinstance(self.stdin, OProc):
+                self._stdin_stream = \
+                        StreamWriter(self.log.get_child("streamwriter",
+                            "stdin"), self._stdin_fd, self.stdin,
+                            self.call_args["in_bufsize"],
+                            self.call_args["encoding"],
+                            self.call_args["tty_in"])
+
+            stdout_pipe = None
+            if pipe is OProc.STDOUT and not self.call_args["no_pipe"]:
+                stdout_pipe = self._pipe_queue
+
+
+            # this represents the connection from a process's STDOUT fd to
+            # wherever it has to go, sometimes a pipe Queue (that we will use
+            # to pipe data to other processes), and also an internal deque
+            # that we use to aggregate all the output
+            save_stdout = not self.call_args["no_out"] and \
+                (self.call_args["tee"] in (True, "out") or stdout is None)
+
+
+            # if we're piping directly into another process's filedescriptor, we
+            # bypass reading from the stdout stream altogether, because we've
+            # already hooked up this processes's stdout fd to the other
+            # processes's stdin fd
+            self._stdout_stream = None
+            if self.call_args["piped"] != "direct":
+                if callable(stdout):
+                    stdout = construct_streamreader_callback(self, stdout)
+                self._stdout_stream = \
+                        StreamReader(self.log.get_child("streamreader",
+                            "stdout"), self._stdout_fd, stdout, self._stdout,
+                            self.call_args["out_bufsize"],
+                            self.call_args["encoding"],
+                            self.call_args["decode_errors"], stdout_pipe,
+                            save_data=save_stdout)
+
+            if stderr is OProc.STDOUT or self._single_tty:
+                self._stderr_stream = None
+            else:
+                stderr_pipe = None
+                if pipe is OProc.STDERR and not self.call_args["no_pipe"]:
+                    stderr_pipe = self._pipe_queue
+
+                save_stderr = not self.call_args["no_err"] and \
+                    (self.call_args["tee"] in ("err",) or stderr is None)
+
+                if callable(stderr):
+                    stderr = construct_streamreader_callback(self, stderr)
+
+                self._stderr_stream = StreamReader(Logger("streamreader"),
+                    self._stderr_fd, stderr, self._stderr,
+                    self.call_args["err_bufsize"], self.call_args["encoding"],
+                    self.call_args["decode_errors"], stderr_pipe,
+                    save_data=save_stderr)
+
+
+            # start the main io threads
+            # stdin thread is not needed if we are connecting from another process's stdout pipe
+            self._input_thread = None
+            if self._stdin_stream:
+                self._input_thread = _start_daemon_thread(self.input_thread,
+                        self._stdin_stream)
+
+            self._output_thread = _start_daemon_thread(self.output_thread,
+                    self._stdout_stream, self._stderr_stream,
+                    self.call_args["timeout"], self.started,
+                    self.call_args["timeout_signal"])
+
+
+    def __repr__(self):
+        return "<Process %d %r>" % (self.pid, self.cmd[:500])
+
+
+    def change_in_bufsize(self, buf):
+        self._stdin_stream.stream_bufferer.change_buffering(buf)
+
+    def change_out_bufsize(self, buf):
+        self._stdout_stream.stream_bufferer.change_buffering(buf)
+
+    def change_err_bufsize(self, buf):
+        self._stderr_stream.stream_bufferer.change_buffering(buf)
+
+
+    def input_thread(self, stdin):
+        """ this is run in a separate thread.  it writes into our process's
+        stdin (a streamwriter) and waits the process to end AND everything that
+        can be written to be written """
+        done = False
+        while not done and self.is_alive():
+            self.log.debug("%r ready for more input", stdin)
+            done = stdin.write()
+
+        stdin.close()
+
+
+    def output_thread(self, stdout, stderr, timeout, started, timeout_exc):
+        """ this function is run in a separate thread.  it reads from the
+        process's stdout stream (a streamreader), and waits for it to claim that
+        its done """
+
+        readers = []
+        errors = []
+
+        if stdout is not None:
+            readers.append(stdout)
+            errors.append(stdout)
+        if stderr is not None:
+            readers.append(stderr)
+            errors.append(stderr)
+
+        # this is our select loop for polling stdout or stderr that is ready to
+        # be read and processed.  if one of those streamreaders indicate that it
+        # is done altogether being read from, we remove it from our list of
+        # things to poll.  when no more things are left to poll, we leave this
+        # loop and clean up
+        while readers:
+            outputs, inputs, err = select.select(readers, [], errors, 0.1)
+
+            # stdout and stderr
+            for stream in outputs:
+                self.log.debug("%r ready to be read from", stream)
+                done = stream.read()
+                if done:
+                    readers.remove(stream)
+
+            for stream in err:
+                pass
+
+            # test if the process has been running too long
+            if timeout:
+                now = time.time()
+                if now - started > timeout:
+                    self.log.debug("we've been running too long")
+                    self.timed_out = True
+                    self.signal(timeout_exc)
+
+
+        # this is here because stdout may be the controlling TTY, and
+        # we can't close it until the process has ended, otherwise the
+        # child will get SIGHUP.  typically, if we've broken out of
+        # the above loop, and we're here, the process is just about to
+        # end, so it's probably ok to aggressively poll self.is_alive()
+        #
+        # the other option to this would be to do the CTTY close from
+        # the method that does the actual os.waitpid() call, but the
+        # problem with that is that the above loop might still be
+        # running, and closing the fd will cause some operation to
+        # fail.  this is less complex than wrapping all the ops
+        # in the above loop with out-of-band fd-close exceptions
+        while self.is_alive():
+            time.sleep(0.001)
+
+        if stdout:
+            stdout.close()
+
+        if stderr:
+            stderr.close()
+
+
+    @property
+    def stdout(self):
+        return "".encode(self.call_args["encoding"]).join(self._stdout)
+
+    @property
+    def stderr(self):
+        return "".encode(self.call_args["encoding"]).join(self._stderr)
+
+
+    def signal(self, sig):
+        self.log.debug("sending signal %d", sig)
+        try:
+            os.kill(self.pid, sig)
+        except OSError:
+            pass
+
+    def kill(self):
+        self.log.debug("killing")
+        self.signal(signal.SIGKILL)
+
+    def terminate(self):
+        self.log.debug("terminating")
+        self.signal(signal.SIGTERM)
+
+
+    def is_alive(self):
+        """ polls if our child process has completed, without blocking.  this
+        method has side-effects, such as setting our exit_code, if we happen to
+        see our child exit while this is running """
+
+        if self.exit_code is not None:
+            return False
+
+        # what we're doing here essentially is making sure that the main thread
+        # (or another thread), isn't calling .wait() on the process.  because
+        # .wait() calls os.waitpid(self.pid, 0), we can't do an os.waitpid
+        # here...because if we did, and the process exited while in this
+        # thread, the main thread's os.waitpid(self.pid, 0) would raise OSError
+        # (because the process ended in another thread).
+        #
+        # so essentially what we're doing is, using this lock, checking if
+        # we're calling .wait(), and if we are, let .wait() get the exit code
+        # and handle the status, otherwise let us do it.
+        acquired = self._wait_lock.acquire(False)
+        if not acquired:
+            if self.exit_code is not None:
+                return False
+            return True
+
+        try:
+            # WNOHANG is just that...we're calling waitpid without hanging...
+            # essentially polling the process.  the return result is (0, 0) if
+            # there's no process status, so we check that pid == self.pid below
+            # in order to determine how to proceed
+            pid, exit_code = os.waitpid(self.pid, os.WNOHANG)
+            if pid == self.pid:
+                self.exit_code = handle_process_exit_code(exit_code)
+                return False
+
+        # no child process
+        except OSError:
+            return False
+        else:
+            return True
+        finally:
+            self._wait_lock.release()
+
+
+    def wait(self):
+        """ waits for the process to complete, handles the exit code """
+
+        self.log.debug("acquiring wait lock to wait for completion")
+        # using the lock in a with-context blocks, which is what we want if
+        # we're running wait()
+        with self._wait_lock:
+            self.log.debug("got wait lock")
+
+            if self.exit_code is None:
+                self.log.debug("exit code not set, waiting on pid")
+                pid, exit_code = os.waitpid(self.pid, 0) # blocks
+                self.exit_code = handle_process_exit_code(exit_code)
+            else:
+                self.log.debug("exit code already set (%d), no need to wait", self.exit_code)
+
+            # we may not have a thread for stdin, if the pipe has been connected
+            # via _piped="direct"
+            if self._input_thread:
+                self._input_thread.join()
+
+            # wait for our stdout and stderr streamreaders to finish reading and
+            # aggregating the process output
+            self._output_thread.join()
+
+            return self.exit_code
+
+
+
+
+class DoneReadingForever(Exception): pass
+class NotYetReadyToRead(Exception): pass
+
+
+def determine_how_to_read_input(input_obj):
+    """ given some kind of input object, return a function that knows how to
+    read chunks of that input object.
+    
+    each reader function should return a chunk and raise a DoneReadingForever
+    exception, or return None, when there's no more data to read
+
+    NOTE: the function returned does not need to care much about the requested
+    buffering type (eg, unbuffered vs newline-buffered).  the StreamBufferer
+    will take care of that.  these functions just need to return a
+    reasonably-sized chunk of data. """
+
+    get_chunk = None
+
+    if isinstance(input_obj, Queue):
+        log_msg = "queue"
+        get_chunk = get_queue_chunk_reader(input_obj)
+
+    elif callable(input_obj):
+        log_msg = "callable"
+        get_chunk = get_callable_chunk_reader(input_obj)
+
+    # also handles stringio
+    elif hasattr(input_obj, "read"):
+        log_msg = "file descriptor"
+        get_chunk = get_file_chunk_reader(input_obj)
+
+    elif isinstance(input_obj, basestring):
+        log_msg = "string"
+        get_chunk = get_iter_string_reader(input_obj)
+
+    else:
+        log_msg = "general iterable"
+        get_chunk = get_iter_chunk_reader(iter(input_obj))
+
+    return get_chunk, log_msg
+
+
+
+def get_queue_chunk_reader(stdin):
+    def fn():
+        try:
+            chunk = stdin.get(True, 0.01)
+        except Empty:
+            raise NotYetReadyToRead
+        if chunk is None:
+            raise DoneReadingForever
+        return chunk
+    return fn
+
+
+def get_callable_chunk_reader(stdin):
+    def fn():
+        try:
+            return stdin()
+        except:
+            raise DoneReadingForever
+    return fn
+
+
+def get_iter_string_reader(stdin):
+    """ return an iterator that returns a chunk of a string every time it is
+    called.  notice that even though bufsize_type might be line buffered, we're
+    not doing any line buffering here.  that's because our StreamBufferer
+    handles all buffering.  we just need to return a reasonable-sized chunk. """
+    bufsize = 1024
+    iter_str = (stdin[i:i + bufsize] for i in range(0, len(stdin), bufsize))
+    return get_iter_chunk_reader(iter_str)
+
+
+def get_iter_chunk_reader(stdin):
+    def fn():
+        try:
+            if IS_PY3:
+                chunk = stdin.__next__()
+            else:
+                chunk = stdin.next()
+            return chunk
+        except StopIteration:
+            raise DoneReadingForever
+    return fn
+
+def get_file_chunk_reader(stdin):
+    bufsize = 1024
+
+    def fn():
+        chunk = stdin.read(bufsize)
+        if not chunk:
+            raise DoneReadingForever
+        else:
+            return chunk
+    return fn
+
+
+def bufsize_type_to_bufsize(bf_type):
+    """ for a given bufsize type, return the actual bufsize we will read.
+    notice that although 1 means "newline-buffered", we're reading a chunk size
+    of 1024.  this is because we have to read something.  we let a
+    StreamBufferer instance handle splitting our chunk on newlines """
+
+    # newlines
+    if bf_type == 1:
+        bufsize = 1024
+    # unbuffered
+    elif bf_type == 0:
+        bufsize = 1
+    # or buffered by specific amount
+    else:
+        bufsize = bf_type
+
+    return bufsize
+
+
+
+class StreamWriter(object):
+    """ StreamWriter reads from some input (the stdin param) and writes to a fd
+    (the stream param).  the stdin may be a Queue, a callable, something with
+    the "read" method, a string, or an iterable """
+
+    def __init__(self, log, stream, stdin, bufsize_type, encoding, tty_in):
+        self.stream = stream
+        self.stdin = stdin
+
+        self.log = log
+        self.encoding = encoding
+        self.tty_in = tty_in
+
+
+        self.stream_bufferer = StreamBufferer(bufsize_type, self.encoding)
+        self.get_chunk, log_msg = determine_how_to_read_input(stdin)
+        self.log.debug("parsed stdin as a %s", log_msg)
+
+
+    def fileno(self):
+        """ defining this allows us to do select.select on an instance of this
+        class """
+        return self.stream
+
+
+
+    def write(self):
+        """ attempt to get a chunk of data to write to our child process's
+        stdin, then write it.  the return value answers the questions "are we
+        done writing forever?" """
+
+        # get_chunk may sometimes return bytes, and sometimes returns trings
+        # because of the nature of the different types of STDIN objects we
+        # support
+        try:
+            chunk = self.get_chunk()
+            if chunk is None:
+                raise DoneReadingForever
+
+        except DoneReadingForever:
+            self.log.debug("done reading")
+
+            if self.tty_in:
+                # EOF time
+                try:
+                    char = termios.tcgetattr(self.stream)[6][termios.VEOF]
+                except:
+                    char = chr(4).encode()
+                os.write(self.stream, char)
+
+            return True
+
+        except NotYetReadyToRead:
+            self.log.debug("received no data")
+            return False
+
+        # if we're not bytes, make us bytes
+        if IS_PY3 and hasattr(chunk, "encode"):
+            chunk = chunk.encode(self.encoding)
+
+        for proc_chunk in self.stream_bufferer.process(chunk):
+            self.log.debug("got chunk size %d: %r", len(proc_chunk),
+                    proc_chunk[:30])
+
+            self.log.debug("writing chunk to process")
+            try:
+                os.write(self.stream, proc_chunk)
+            except OSError:
+                self.log.debug("OSError writing stdin chunk")
+                return True
+
+
+    def close(self):
+        self.log.debug("closing, but flushing first")
+        chunk = self.stream_bufferer.flush()
+        self.log.debug("got chunk size %d to flush: %r", len(chunk), chunk[:30])
+        try:
+            if chunk:
+                os.write(self.stream, chunk)
+
+            if not self.tty_in:
+                self.log.debug("we used a TTY, so closing the stream")
+                os.close(self.stream)
+
+        except OSError:
+            pass
+
+
+
+def determine_how_to_feed_output(handler, encoding, decode_errors):
+    if callable(handler):
+        process, finish = get_callback_chunk_consumer(handler, encoding,
+                decode_errors)
+    elif isinstance(handler, cStringIO):
+        process, finish = get_cstringio_chunk_consumer(handler)
+    elif isinstance(handler, StringIO):
+        process, finish = get_stringio_chunk_consumer(handler, encoding,
+                decode_errors)
+    elif hasattr(handler, "write"):
+        process, finish = get_file_chunk_consumer(handler)
+    else:
+        process = lambda chunk: False
+        finish = lambda: None
+
+    return process, finish
+
+
+def get_file_chunk_consumer(handler):
+    def process(chunk):
+        handler.write(chunk)
+        # we should flush on an fd.  chunk is already the correctly-buffered
+        # size, so we don't need the fd buffering as well
+        handler.flush()
+        return False
+
+    def finish():
+        if hasattr(handler, "flush"):
+            handler.flush()
+
+    return process, finish
+
+def get_callback_chunk_consumer(handler, encoding, decode_errors):
+    def process(chunk):
+        # try to use the encoding first, if that doesn't work, send
+        # the bytes, because it might be binary
+        try:
+            chunk = chunk.decode(encoding, decode_errors)
+        except UnicodeDecodeError:
+            pass
+        return handler(chunk)
+
+    def finish():
+        pass
+
+    return process, finish
+
+def get_cstringio_chunk_consumer(handler):
+    def process(chunk):
+        handler.write(chunk)
+        return False
+
+    def finish():
+        pass
+
+    return process, finish
+
+
+def get_stringio_chunk_consumer(handler, encoding, decode_errors):
+    def process(chunk):
+        handler.write(chunk.decode(encoding, decode_errors))
+        return False
+
+    def finish():
+        pass
+
+    return process, finish
+
+
+class StreamReader(object):
+    """ reads from some output (the stream) and sends what it just read to the
+    handler.  """
+    def __init__(self, log, stream, handler, buffer, bufsize_type, encoding,
+            decode_errors, pipe_queue=None, save_data=True):
+        self.stream = stream
+        self.buffer = buffer
+        self.save_data = save_data
+        self.encoding = encoding
+        self.decode_errors = decode_errors
+
+        self.pipe_queue = None
+        if pipe_queue:
+            self.pipe_queue = weakref.ref(pipe_queue)
+
+        self.log = log
+
+        self.stream_bufferer = StreamBufferer(bufsize_type, self.encoding,
+                self.decode_errors)
+        self.bufsize = bufsize_type_to_bufsize(bufsize_type)
+
+        self.process_chunk, self.finish_chunk_processor = \
+                determine_how_to_feed_output(handler, encoding, decode_errors)
+
+        self.should_quit = False
+
+
+    def fileno(self):
+        """ defining this allows us to do select.select on an instance of this
+        class """
+        return self.stream
+
+    def close(self):
+        chunk = self.stream_bufferer.flush()
+        self.log.debug("got chunk size %d to flush: %r", len(chunk), chunk[:30])
+        if chunk:
+            self.write_chunk(chunk)
+
+        self.finish_chunk_processor()
+
+        if self.pipe_queue and self.save_data:
+            self.pipe_queue().put(None)
+
+        try:
+            os.close(self.stream)
+        except OSError:
+            pass
+
+
+    def write_chunk(self, chunk):
+        # in PY3, the chunk coming in will be bytes, so keep that in mind
+
+        if not self.should_quit:
+            self.should_quit = self.process_chunk(chunk)
+
+
+        if self.save_data:
+            self.buffer.append(chunk)
+
+            if self.pipe_queue:
+                self.log.debug("putting chunk onto pipe: %r", chunk[:30])
+                self.pipe_queue().put(chunk)
+
+
+    def read(self):
+        # if we're PY3, we're reading bytes, otherwise we're reading
+        # str
+        try:
+            chunk = os.read(self.stream, self.bufsize)
+        except OSError as e:
+            self.log.debug("got errno %d, done reading", e.errno)
+            return True
+        if not chunk:
+            self.log.debug("got no chunk, done reading")
+            return True
+
+        self.log.debug("got chunk size %d: %r", len(chunk), chunk[:30])
+        for chunk in self.stream_bufferer.process(chunk):
+            self.write_chunk(chunk)
+
+
+
+
+class StreamBufferer(object):
+    """ this is used for feeding in chunks of stdout/stderr, and breaking it up
+    into chunks that will actually be put into the internal buffers.  for
+    example, if you have two processes, one being piped to the other, and you
+    want that, first process to feed lines of data (instead of the chunks
+    however they come in), OProc will use an instance of this class to chop up
+    the data and feed it as lines to be sent down the pipe """
+
+    def __init__(self, buffer_type, encoding=DEFAULT_ENCODING,
+            decode_errors="strict"):
+        # 0 for unbuffered, 1 for line, everything else for that amount
+        self.type = buffer_type
+        self.buffer = []
+        self.n_buffer_count = 0
+        self.encoding = encoding
+        self.decode_errors = decode_errors
+
+        # this is for if we change buffering types.  if we change from line
+        # buffered to unbuffered, its very possible that our self.buffer list
+        # has data that was being saved up (while we searched for a newline).
+        # we need to use that up, so we don't lose it
+        self._use_up_buffer_first = False
+
+        # the buffering lock is used because we might chance the buffering
+        # types from a different thread.  for example, if we have a stdout
+        # callback, we might use it to change the way stdin buffers.  so we
+        # lock
+        self._buffering_lock = threading.RLock()
+        self.log = Logger("stream_bufferer")
+
+
+    def change_buffering(self, new_type):
+        # TODO, when we stop supporting 2.6, make this a with context
+        self.log.debug("acquiring buffering lock for changing buffering")
+        self._buffering_lock.acquire()
+        self.log.debug("got buffering lock for changing buffering")
+        try:
+            if new_type == 0:
+                self._use_up_buffer_first = True
+
+            self.type = new_type
+        finally:
+            self._buffering_lock.release()
+            self.log.debug("released buffering lock for changing buffering")
+
+
+    def process(self, chunk):
+        # MAKE SURE THAT THE INPUT IS PY3 BYTES
+        # THE OUTPUT IS ALWAYS PY3 BYTES
+
+        # TODO, when we stop supporting 2.6, make this a with context
+        self.log.debug("acquiring buffering lock to process chunk (buffering: %d)", self.type)
+        self._buffering_lock.acquire()
+        self.log.debug("got buffering lock to process chunk (buffering: %d)", self.type)
+        try:
+            # we've encountered binary, permanently switch to N size buffering
+            # since matching on newline doesn't make sense anymore
+            if self.type == 1:
+                try:
+                    chunk.decode(self.encoding, self.decode_errors)
+                except:
+                    self.log.debug("detected binary data, changing buffering")
+                    self.change_buffering(1024)
+
+            # unbuffered
+            if self.type == 0:
+                if self._use_up_buffer_first:
+                    self._use_up_buffer_first = False
+                    to_write = self.buffer
+                    self.buffer = []
+                    to_write.append(chunk)
+                    return to_write
+
+                return [chunk]
+
+            # line buffered
+            # we must decode the bytes before we try to match on newline
+            elif self.type == 1:
+                total_to_write = []
+                chunk = chunk.decode(self.encoding, self.decode_errors)
+                while True:
+                    newline = chunk.find("\n")
+                    if newline == -1:
+                        break
+
+                    chunk_to_write = chunk[:newline + 1]
+                    if self.buffer:
+                        # this is ugly, but it's designed to take the existing
+                        # bytes buffer, join it together, tack on our latest
+                        # chunk, then convert the whole thing to a string.
+                        # it's necessary, i'm sure.  read the whole block to
+                        # see why.
+                        chunk_to_write = "".encode(self.encoding).join(self.buffer) \
+                            + chunk_to_write.encode(self.encoding)
+                        chunk_to_write = chunk_to_write.decode(self.encoding)
+
+                        self.buffer = []
+                        self.n_buffer_count = 0
+
+                    chunk = chunk[newline + 1:]
+                    total_to_write.append(chunk_to_write.encode(self.encoding))
+
+                if chunk:
+                    self.buffer.append(chunk.encode(self.encoding))
+                    self.n_buffer_count += len(chunk)
+                return total_to_write
+
+            # N size buffered
+            else:
+                total_to_write = []
+                while True:
+                    overage = self.n_buffer_count + len(chunk) - self.type
+                    if overage >= 0:
+                        ret = "".encode(self.encoding).join(self.buffer) + chunk
+                        chunk_to_write = ret[:self.type]
+                        chunk = ret[self.type:]
+                        total_to_write.append(chunk_to_write)
+                        self.buffer = []
+                        self.n_buffer_count = 0
+                    else:
+                        self.buffer.append(chunk)
+                        self.n_buffer_count += len(chunk)
+                        break
+                return total_to_write
+        finally:
+            self._buffering_lock.release()
+            self.log.debug("released buffering lock for processing chunk (buffering: %d)", self.type)
+
+
+    def flush(self):
+        self.log.debug("acquiring buffering lock for flushing buffer")
+        self._buffering_lock.acquire()
+        self.log.debug("got buffering lock for flushing buffer")
+        try:
+            ret = "".encode(self.encoding).join(self.buffer)
+            self.buffer = []
+            return ret
+        finally:
+            self._buffering_lock.release()
+            self.log.debug("released buffering lock for flushing buffer")
+
+
+
+@contextmanager
+def pushd(path):
+    """ pushd is just a specialized form of args, where we're passing in the
+    current working directory """
+    with args(_cwd=path):
+        yield
+
+
+@contextmanager
+def args(*args, **kwargs):
+    """ allows us to temporarily override all the special keyword parameters in
+    a with context """
+    call_args = Command._call_args
+    old_args = call_args.copy()
+
+    for key,value in kwargs.items():
+        key = key.lstrip("_")
+        call_args[key] = value
+
+    yield
+    call_args.update(old_args)
+
+
+
+class Environment(dict):
+    """ this allows lookups to names that aren't found in the global scope to be
+    searched for as a program name.  for example, if "ls" isn't found in this
+    module's scope, we consider it a system program and try to find it.
+
+    we use a dict instead of just a regular object as the base class because the
+    exec() statement used in this file requires the "globals" argument to be a
+    dictionary """
+
+
+    # this is a list of all of the names that the sh module exports that will
+    # not resolve to functions.  we don't want to accidentally shadow real
+    # commands with functions/imports that we define in sh.py.  for example,
+    # "import time" may override the time system program
+    whitelist = set([
+        "Command",
+        "CommandNotFound",
+        "DEFAULT_ENCODING",
+        "DoneReadingForever",
+        "ErrorReturnCode",
+        "NotYetReadyToRead",
+        "SignalException",
+        "TimeoutException",
+        "__project_url__",
+        "__version__",
+        "args",
+        "glob",
+        "pushd",
+    ])
+
+    def __init__(self, globs, baked_args={}):
+        self.globs = globs
+        self.baked_args = baked_args
+        self.disable_whitelist = False
+
+    def __setitem__(self, k, v):
+        self.globs[k] = v
+
+    def __getitem__(self, k):
+        # if we first import "_disable_whitelist" from sh, we can import
+        # anything defined in the global scope of sh.py.  this is useful for our
+        # tests
+        if k == "_disable_whitelist":
+            self.disable_whitelist = True
+            return None
+
+        # we're trying to import something real (maybe), see if it's in our
+        # global scope
+        if k in self.whitelist or self.disable_whitelist:
+            try:
+                return self.globs[k]
+            except KeyError:
+                pass
+
+        # somebody tried to be funny and do "from sh import *"
+        if k == "__all__":
+            raise AttributeError("Cannot import * from sh. \
+Please import sh or import programs individually.")
+
+
+        # check if we're naming a dynamically generated ReturnCode exception
+        exc = get_exc_from_name(k)
+        if exc:
+            return exc
+
+
+        # https://github.com/ipython/ipython/issues/2577
+        # https://github.com/amoffat/sh/issues/97#issuecomment-10610629
+        if k.startswith("__") and k.endswith("__"):
+            raise AttributeError
+
+        # how about an environment variable?
+        try:
+            return os.environ[k]
+        except KeyError:
+            pass
+
+        # is it a custom builtin?
+        builtin = getattr(self, "b_" + k, None)
+        if builtin:
+            return builtin
+
+        # it must be a command then
+        # we use _create instead of instantiating the class directly because
+        # _create uses resolve_program, which will automatically do underscore-
+        # to-dash conversions.  instantiating directly does not use that
+        return Command._create(k, **self.baked_args)
+
+
+    # methods that begin with "b_" are custom builtins and will override any
+    # program that exists in our path.  this is useful for things like
+    # common shell builtins that people are used to, but which aren't actually
+    # full-fledged system binaries
+
+    def b_cd(self, path):
+        os.chdir(path)
+
+    def b_which(self, program):
+        return which(program)
+
+
+
+
+def run_repl(env): # pragma: no cover
+    banner = "\n>> sh v{version}\n>> https://github.com/amoffat/sh\n"
+
+    print(banner.format(version=__version__))
+    while True:
+        try:
+            line = raw_input("sh> ")
+        except (ValueError, EOFError):
+            break
+
+        try:
+            exec(compile(line, "<dummy>", "single"), env, env)
+        except SystemExit:
+            break
+        except:
+            print(traceback.format_exc())
+
+    # cleans up our last line
+    print("")
+
+
+
+
+# this is a thin wrapper around THIS module (we patch sys.modules[__name__]).
+# this is in the case that the user does a "from sh import whatever"
+# in other words, they only want to import certain programs, not the whole
+# system PATH worth of commands.  in this case, we just proxy the
+# import lookup to our Environment class
+class SelfWrapper(ModuleType):
+    def __init__(self, self_module, baked_args={}):
+        # this is super ugly to have to copy attributes like this,
+        # but it seems to be the only way to make reload() behave
+        # nicely.  if i make these attributes dynamic lookups in
+        # __getattr__, reload sometimes chokes in weird ways...
+        for attr in ["__builtins__", "__doc__", "__name__", "__package__"]:
+            setattr(self, attr, getattr(self_module, attr, None))
+
+        # python 3.2 (2.7 and 3.3 work fine) breaks on osx (not ubuntu)
+        # if we set this to None.  and 3.3 needs a value for __path__
+        self.__path__ = []
+        self.__self_module = self_module
+        self.__env = Environment(globals(), baked_args)
+
+    def __setattr__(self, name, value):
+        if hasattr(self, "__env"):
+            self.__env[name] = value
+        else:
+            ModuleType.__setattr__(self, name, value)
+
+    def __getattr__(self, name):
+        if name == "__env":
+            raise AttributeError
+        return self.__env[name]
+
+    # accept special keywords argument to define defaults for all operations
+    # that will be processed with given by return SelfWrapper
+    def __call__(self, **kwargs):
+        return SelfWrapper(self.__self_module, kwargs)
+
+
+
+# we're being run as a stand-alone script
+if __name__ == "__main__": # pragma: no cover
+    try:
+        arg = sys.argv.pop(1)
+    except:
+        arg = None
+
+    if arg == "test":
+        import subprocess
+
+        def run_test(version, locale):
+            py_version = "python%s" % version
+            py_bin = which(py_version)
+
+            if py_bin:
+                print("Testing %s, locale %r" % (py_version.capitalize(),
+                    locale))
+
+                env = os.environ.copy()
+                env["LANG"] = locale
+                p = subprocess.Popen([py_bin, os.path.join(THIS_DIR, "test.py")]
+                    + sys.argv[1:], env=env)
+                return_code = p.wait()
+
+                if return_code != 0:
+                    exit(1)
+            else:
+                print("Couldn't find %s, skipping" % py_version.capitalize())
+
+        versions = ("2.6", "2.7", "3.1", "3.2", "3.3", "3.4")
+        locales = ("en_US.UTF-8", "C")
+        for locale in locales:
+            for version in versions:
+                run_test(version, locale)
+
+    else:
+        env = Environment(globals())
+        run_repl(env)
+
+# we're being imported from somewhere
+else:
+    self = sys.modules[__name__]
+    sys.modules[__name__] = SelfWrapper(self)
