def _redirect_streams(r, loc=None): """Returns stdin, stdout, stderr tuple of redirections.""" stdin = stdout = stderr = None no_ampersand = r.replace("&", "") # special case of redirecting stderr to stdout if no_ampersand in _E2O_MAP: stderr = subprocess.STDOUT return stdin, stdout, stderr elif no_ampersand in _O2E_MAP: stdout = 2 # using 2 as a flag, rather than using a file object return stdin, stdout, stderr # get streams orig, mode, dest = _parse_redirects(r) if mode == "r": stdin = safe_open(loc, mode) elif mode in _WRITE_MODES: if orig in _REDIR_ALL: stdout = stderr = safe_open(loc, mode) elif orig in _REDIR_OUT: stdout = safe_open(loc, mode) elif orig in _REDIR_ERR: stderr = safe_open(loc, mode) else: raise XonshError("Unrecognized redirection command: {}".format(r)) else: raise XonshError("Unrecognized redirection command: {}".format(r)) return stdin, stdout, stderr
def safe_open(fname, mode, buffering=-1): """Safely attempts to open a file in for xonsh subprocs.""" # file descriptors try: return io.open(fname, mode, buffering=buffering) except PermissionError: raise XonshError("xonsh: {0}: permission denied".format(fname)) except FileNotFoundError: raise XonshError("xonsh: {0}: no such file or directory".format(fname)) except Exception: raise XonshError("xonsh: {0}: unable to open file".format(fname))
def _open(fname, mode): # file descriptors if isinstance(fname, int): return fname try: return open(fname, mode) except PermissionError: raise XonshError('xonsh: {0}: permission denied'.format(fname)) except FileNotFoundError: raise XonshError('xonsh: {0}: no such file or directory'.format(fname)) except Exception: raise XonshError('xonsh: {0}: unable to open file'.format(fname))
def __init__(self, ctx=None, shell_type=None, **kwargs): self._init_environ(ctx) env = builtins.__xonsh_env__ # pick a valid shell if shell_type is not None: env['SHELL_TYPE'] = shell_type shell_type = env.get('SHELL_TYPE') if shell_type == 'prompt_toolkit': if not is_prompt_toolkit_available(): warn('prompt_toolkit is not available, using readline instead.') shell_type = env['SHELL_TYPE'] = 'readline' # actually make the shell if shell_type == 'prompt_toolkit': from xonsh.prompt_toolkit_shell import PromptToolkitShell self.shell = PromptToolkitShell(execer=self.execer, ctx=self.ctx, **kwargs) elif shell_type == 'readline': from xonsh.readline_shell import ReadlineShell self.shell = ReadlineShell(execer=self.execer, ctx=self.ctx, **kwargs) else: raise XonshError('{} is not recognized as a shell type'.format( shell_type)) # allows history garbace colector to start running builtins.__xonsh_history__.gc.wait_for_shell = False
def bang_n(args, stdin=None): """Re-runs the nth command as specified in the argument.""" global _BANG_N_PARSER if _BANG_N_PARSER is None: parser = _BANG_N_PARSER = ArgumentParser( '!n', usage='!n <n>', description="Re-runs the nth command as specified in the argument." ) parser.add_argument('n', type=int, help='the command to rerun, may be negative') else: parser = _BANG_N_PARSER ns = parser.parse_args(args) hist = builtins.__xonsh_history__ nhist = len(hist) n = nhist + ns.n if ns.n < 0 else ns.n if n < 0 or n >= nhist: raise IndexError('n out of range, {0} for history len {1}'.format( ns.n, nhist)) cmd = hist.inps[n] if cmd.startswith('!'): raise XonshError('xonsh: error: recursive call to !n') builtins.execx(cmd)
def cmds_to_specs(cmds, captured=False): """Converts a list of cmds to a list of SubprocSpec objects that are ready to be executed. """ # first build the subprocs independently and separate from the redirects i = 0 specs = [] redirects = [] for cmd in cmds: if isinstance(cmd, str): redirects.append(cmd) else: spec = SubprocSpec.build(cmd, captured=captured) spec.pipeline_index = i specs.append(spec) i += 1 # now modify the subprocs based on the redirects. for i, redirect in enumerate(redirects): if redirect == "|": # these should remain integer file descriptors, and not Python # file objects since they connect processes. r, w = os.pipe() specs[i].stdout = w specs[i + 1].stdin = r elif redirect == "&" and i == len(redirects) - 1: specs[i].background = True else: raise XonshError("unrecognized redirect {0!r}".format(redirect)) # Apply boundary conditions _update_last_spec(specs[-1]) return specs
def __init__(self, ctx=None, shell_type=None, **kwargs): self._init_environ(ctx) env = builtins.__xonsh_env__ if shell_type is not None: env['SHELL_TYPE'] = shell_type if env['SHELL_TYPE'] == 'prompt_toolkit': if not is_prompt_toolkit_available(): warn( 'prompt_toolkit is not available, using readline instead.') env['SHELL_TYPE'] = 'readline' if env['SHELL_TYPE'] == 'prompt_toolkit': from xonsh.prompt_toolkit_shell import PromptToolkitShell self.shell = PromptToolkitShell(execer=self.execer, ctx=self.ctx, **kwargs) elif env['SHELL_TYPE'] == 'readline': from xonsh.readline_shell import ReadlineShell self.shell = ReadlineShell(execer=self.execer, ctx=self.ctx, **kwargs) else: raise XonshError('{} is not recognized as a shell type'.format( env['SHELL_TYPE']))
def _run_binary(self, kwargs): try: bufsize = 1 p = self.cls(self.cmd, bufsize=bufsize, **kwargs) except PermissionError: e = 'xonsh: subprocess mode: permission denied: {0}' raise XonshError(e.format(self.cmd[0])) except FileNotFoundError: cmd0 = self.cmd[0] e = 'xonsh: subprocess mode: command not found: {0}'.format(cmd0) env = builtins.__xonsh_env__ sug = suggest_commands(cmd0, env, builtins.aliases) if len(sug.strip()) > 0: e += '\n' + suggest_commands(cmd0, env, builtins.aliases) raise XonshError(e) return p
def __init__(self, ctx=None, shell_type=None, config=None, rc=None, **kwargs): """ Parameters ---------- ctx : Mapping, optional The execution context for the shell (e.g. the globals namespace). If none, this is computed by loading the rc files. If not None, this no additional context is computed and this is used directly. shell_type : str, optional The shell type to start, such as 'readline', 'prompt_toolkit', or 'random'. config : str, optional Path to configuration file. rc : list of str, optional Sequence of paths to run control files. """ self.login = kwargs.get('login', True) self.stype = shell_type self._init_environ(ctx, config, rc, kwargs.get('scriptcache', True), kwargs.get('cacheall', False)) env = builtins.__xonsh_env__ # pick a valid shell if shell_type is not None: env['SHELL_TYPE'] = shell_type shell_type = env.get('SHELL_TYPE') if shell_type == 'best': shell_type = best_shell_type() elif shell_type == 'random': shell_type = random.choice(('readline', 'prompt_toolkit')) if shell_type == 'prompt_toolkit': if not is_prompt_toolkit_available(): warn( 'prompt_toolkit is not available, using readline instead.') shell_type = env['SHELL_TYPE'] = 'readline' # actually make the shell if shell_type == 'none': from xonsh.base_shell import BaseShell as shell_class elif shell_type == 'prompt_toolkit': vptk = prompt_toolkit_version() major, minor = [int(x) for x in vptk.split('.')[:2]] if (major, minor) < ( 0, 57) or vptk == '<0.57': # TODO: remove in future msg = ('prompt-toolkit version < v0.57 and may not work as ' 'expected. Please update.') warn(msg, RuntimeWarning) from xonsh.ptk.shell import PromptToolkitShell as shell_class elif shell_type == 'readline': from xonsh.readline_shell import ReadlineShell as shell_class else: raise XonshError( '{} is not recognized as a shell type'.format(shell_type)) self.shell = shell_class(execer=self.execer, ctx=self.ctx, **kwargs) # allows history garbace colector to start running builtins.__xonsh_history__.gc.wait_for_shell = False
def __init__(self, ctx=None, shell_type=None, config=None, rc=None, **kwargs): """ Parameters ---------- ctx : Mapping, optional The execution context for the shell (e.g. the globals namespace). If none, this is computed by loading the rc files. If not None, this no additional context is computed and this is used directly. shell_type : str, optional The shell type to start, such as 'readline', 'prompt_toolkit', or 'random'. config : str, optional Path to configuration file. rc : list of str, optional Sequence of paths to run control files. """ self.login = kwargs.get('login', True) self.stype = shell_type self._init_environ(ctx, config, rc, kwargs.get('scriptcache', True), kwargs.get('cacheall', False)) env = builtins.__xonsh_env__ # pick a valid shell -- if no shell is specified by the user, # shell type is pulled from env if shell_type is None: shell_type = env.get('SHELL_TYPE') if shell_type == 'best' or shell_type is None: shell_type = best_shell_type() elif shell_type == 'random': shell_type = random.choice(('readline', 'prompt_toolkit')) if shell_type == 'prompt_toolkit': if not has_prompt_toolkit(): warnings.warn('prompt_toolkit is not available, using ' 'readline instead.') shell_type = 'readline' elif not ptk_version_is_supported(): warnings.warn('prompt-toolkit version < v1.0.0 is not ' 'supported. Please update prompt-toolkit. Using ' 'readline instead.') shell_type = 'readline' env['SHELL_TYPE'] = shell_type # actually make the shell if shell_type == 'none': from xonsh.base_shell import BaseShell as shell_class elif shell_type == 'prompt_toolkit': from xonsh.ptk.shell import PromptToolkitShell as shell_class elif shell_type == 'readline': from xonsh.readline_shell import ReadlineShell as shell_class else: raise XonshError( '{} is not recognized as a shell type'.format(shell_type)) self.shell = shell_class(execer=self.execer, ctx=self.ctx, **kwargs) # allows history garbace colector to start running builtins.__xonsh_history__.gc.wait_for_shell = False
def __init__(self, execer, ctx=None, shell_type=None, **kwargs): """ Parameters ---------- execer : Execer An execer instance capable of running xonsh code. ctx : Mapping, optional The execution context for the shell (e.g. the globals namespace). If none, this is computed by loading the rc files. If not None, this no additional context is computed and this is used directly. shell_type : str, optional The shell type to start, such as 'readline', 'prompt_toolkit', or 'random'. """ self.execer = execer self.ctx = {} if ctx is None else ctx env = builtins.__xonsh_env__ # build history backend before creating shell builtins.__xonsh_history__ = hist = xhm.construct_history( env=env.detype(), ts=[time.time(), None], locked=True) # pick a valid shell -- if no shell is specified by the user, # shell type is pulled from env if shell_type is None: shell_type = env.get('SHELL_TYPE') if shell_type == 'none': # This bricks interactive xonsh # Can happen from the use of .xinitrc, .xsession, etc shell_type = 'best' if shell_type == 'best' or shell_type is None: shell_type = best_shell_type() elif shell_type == 'random': shell_type = random.choice(('readline', 'prompt_toolkit')) if shell_type == 'prompt_toolkit': if not has_prompt_toolkit(): warnings.warn('prompt_toolkit is not available, using ' 'readline instead.') shell_type = 'readline' elif not ptk_version_is_supported(): warnings.warn('prompt-toolkit version < v1.0.0 is not ' 'supported. Please update prompt-toolkit. Using ' 'readline instead.') shell_type = 'readline' self.shell_type = env['SHELL_TYPE'] = shell_type # actually make the shell if shell_type == 'none': from xonsh.base_shell import BaseShell as shell_class elif shell_type == 'prompt_toolkit': from xonsh.ptk.shell import PromptToolkitShell as shell_class elif shell_type == 'readline': from xonsh.readline_shell import ReadlineShell as shell_class else: raise XonshError( '{} is not recognized as a shell type'.format(shell_type)) self.shell = shell_class(execer=self.execer, ctx=self.ctx, **kwargs) # allows history garbage collector to start running if hist.gc is not None: hist.gc.wait_for_shell = False
def _open(fname, mode): # file descriptors if isinstance(fname, int): return fname try: return open(fname, mode) except: raise XonshError('xonsh: {0}: no such file or directory'.format(fname))
def __call__( self, args, stdin=None, stdout=None, stderr=None, spec=None, stack=None ): args = list(self.acc_args) + args if args: msg = "callable alias {f!r} takes no arguments, but {args!f} provided. " msg += "Of these {acc_args!r} were partially applied." raise XonshError(msg.format(f=self.f, args=args, acc_args=self.acc_args)) return self.f()
def stdout(self, value): if self._stdout is None: self._stdout = value elif value is None: pass else: safe_close(value) msg = 'Multiple redirections for stdout for {0!r}' msg = msg.format(' '.join(self.args)) raise XonshError(msg)
def stderr(self, value): if self._stderr is None: self._stderr = value elif value is None: pass else: safe_close(value) msg = "Multiple redirections for stderr for {0!r}" msg = msg.format(" ".join(self.args)) raise XonshError(msg)
def stdin(self, value): if self._stdin is None: self._stdin = value elif value is None: pass else: safe_close(value) msg = "Multiple inputs for stdin for {0!r}" msg = msg.format(" ".join(self.args)) raise XonshError(msg)
def __init__(self, execer, ctx=None, shell_type=None, **kwargs): """ Parameters ---------- execer : Execer An execer instance capable of running xonsh code. ctx : Mapping, optional The execution context for the shell (e.g. the globals namespace). If none, this is computed by loading the rc files. If not None, this no additional context is computed and this is used directly. shell_type : str, optional The shell type to start, such as 'readline', 'prompt_toolkit1', or 'random'. """ self.execer = execer self.ctx = {} if ctx is None else ctx env = XSH.env # build history backend before creating shell if env.get("XONSH_INTERACTIVE"): XSH.history = hist = xhm.construct_history( env=env.detype(), ts=[time.time(), None], locked=True, filename=env.get("XONSH_HISTORY_FILE", None), ) env["XONSH_HISTORY_FILE"] = hist.filename else: XSH.history = hist = DummyHistory() env["XONSH_HISTORY_FILE"] = None shell_type = self.choose_shell_type(shell_type, env) self.shell_type = env["SHELL_TYPE"] = shell_type # actually make the shell if shell_type == "none": from xonsh.base_shell import BaseShell as shell_class elif shell_type == "prompt_toolkit": from xonsh.ptk_shell.shell import PromptToolkitShell as shell_class elif shell_type == "readline": from xonsh.readline_shell import ReadlineShell as shell_class elif shell_type == "jupyter": from xonsh.jupyter_shell import JupyterShell as shell_class elif shell_type == "dumb": from xonsh.dumb_shell import DumbShell as shell_class else: raise XonshError( "{} is not recognized as a shell type".format(shell_type)) self.shell = shell_class(execer=self.execer, ctx=self.ctx, **kwargs) # allows history garbage collector to start running if hist.gc is not None: hist.gc.wait_for_shell = False
def pathsearch(func, s, pymode=False): """ Takes a string and returns a list of file paths that match (regex, glob, or arbitrary search function). """ if (not callable(func) or len(inspect.signature(func).parameters) != 1): error = "%r is not a known path search function" raise XonshError(error % searchfunc) o = func(s) no_match = [] if pymode else [s] return o if len(o) != 0 else no_match
def _get_env_dir(self, venv=None): venv = venv or ... try: env_dir = self.vox[venv].env except KeyError: # check whether the venv is a valid path to an environment if (isinstance(venv, str) and os.path.exists(venv) and os.path.exists(self.vox.get_binary_path( "python", venv))): return venv raise XonshError("No virtualenv is found") return env_dir
def _run_binary(self, kwargs): try: bufsize = 1 p = self.cls(self.cmd, bufsize=bufsize, **kwargs) except PermissionError: e = "xonsh: subprocess mode: permission denied: {0}" raise XonshError(e.format(self.cmd[0])) except FileNotFoundError: cmd0 = self.cmd[0] if len(self.cmd) == 1 and cmd0.endswith("?"): with contextlib.suppress(OSError): return self.cls(["man", cmd0.rstrip("?")], bufsize=bufsize, **kwargs) e = "xonsh: subprocess mode: command not found: {0}".format(cmd0) env = builtins.__xonsh__.env sug = suggest_commands(cmd0, env, builtins.aliases) if len(sug.strip()) > 0: e += "\n" + suggest_commands(cmd0, env, builtins.aliases) raise XonshError(e) return p
def bang_n(args, stdin=None): """Re-runs the nth command as specified in the argument.""" ns = _BANG_N_PARSER.parse_args(args) hist = builtins.__xonsh_history__ nhist = len(hist) n = nhist + ns.n if ns.n < 0 else ns.n if n < 0 or n >= nhist: raise IndexError('n out of range, {0} for history len {1}'.format(ns.n, nhist)) cmd = hist.inps[n] if cmd.startswith('!'): raise XonshError('xonsh: error: recursive call to !n') builtins.execx(cmd)
def _parse_redirects(r, loc=None): """returns origin, mode, destination tuple""" orig, mode, dest = _REDIR_REGEX.match(r).groups() # redirect to fd if dest.startswith("&"): try: dest = int(dest[1:]) if loc is None: loc, dest = dest, "" # NOQA else: e = "Unrecognized redirection command: {}".format(r) raise XonshError(e) except (ValueError, XonshError): raise except Exception: pass mode = _MODES.get(mode, None) if mode == "r" and (len(orig) > 0 or len(dest) > 0): raise XonshError("Unrecognized redirection command: {}".format(r)) elif mode in _WRITE_MODES and len(dest) > 0: raise XonshError("Unrecognized redirection command: {}".format(r)) return orig, mode, dest
def __init__(self, ctx=None, shell_type=None, config=None, rc=None, **kwargs): """ Parameters ---------- ctx : Mapping, optional The execution context for the shell (e.g. the globals namespace). If none, this is computed by loading the rc files. If not None, this no additional context is computed and this is used directly. shell_type : str, optional The shell type to start, such as 'readline', 'prompt_toolkit', or 'random'. config : str, optional Path to configuration file. rc : list of str, optional Sequence of paths to run control files. """ self._init_environ(ctx, config, rc) env = builtins.__xonsh_env__ # pick a valid shell if shell_type is not None: env['SHELL_TYPE'] = shell_type shell_type = env.get('SHELL_TYPE') if shell_type == 'random': shell_type = random.choice(('readline', 'prompt_toolkit')) if shell_type == 'prompt_toolkit': if not is_prompt_toolkit_available(): warn( 'prompt_toolkit is not available, using readline instead.') shell_type = env['SHELL_TYPE'] = 'readline' # actually make the shell if shell_type == 'prompt_toolkit': from xonsh.ptk.shell import PromptToolkitShell self.shell = PromptToolkitShell(execer=self.execer, ctx=self.ctx, **kwargs) elif shell_type == 'readline': from xonsh.readline_shell import ReadlineShell self.shell = ReadlineShell(execer=self.execer, ctx=self.ctx, **kwargs) else: raise XonshError( '{} is not recognized as a shell type'.format(shell_type)) # allows history garbace colector to start running builtins.__xonsh_history__.gc.wait_for_shell = False
def _redirect_streams(r, loc=None): """Returns stdin, stdout, stderr tuple of redirections.""" stdin = stdout = stderr = None # special case of redirecting stderr to stdout if r.replace('&', '') in _E2O_MAP: stderr = subprocess.STDOUT return stdin, stdout, stderr # get streams orig, mode, dest = _parse_redirects(r) if mode == 'r': stdin = safe_open(loc, mode) elif mode in _WRITE_MODES: if orig in _REDIR_ALL: stdout = stderr = safe_open(loc, mode) elif orig in _REDIR_OUT: stdout = safe_open(loc, mode) elif orig in _REDIR_ERR: stderr = safe_open(loc, mode) else: raise XonshError('Unrecognized redirection command: {}'.format(r)) else: raise XonshError('Unrecognized redirection command: {}'.format(r)) return stdin, stdout, stderr
def pathsearch(func, s, pymode=False, pathobj=False): """ Takes a string and returns a list of file paths that match (regex, glob, or arbitrary search function). If pathobj=True, the return is a list of pathlib.Path objects instead of strings. """ if not callable(func) or len(inspect.signature(func).parameters) != 1: error = "%r is not a known path search function" raise XonshError(error % func) o = func(s) if pathobj and pymode: o = list(map(pathlib.Path, o)) no_match = [] if pymode else [s] return o if len(o) != 0 else no_match
def resolve_executable_commands(self): """Resolve command executables, if applicable.""" alias = self.alias if callable(alias): self.cmd.pop(0) return elif alias is None: pass else: self.cmd = alias + self.cmd[1:] if self.binary_loc is None: return try: self.cmd = get_script_subproc_command(self.binary_loc, self.cmd[1:]) except PermissionError: e = 'xonsh: subprocess mode: permission denied: {0}' raise XonshError(e.format(self.cmd[0]))
def resolve_executable_commands(self): """Resolve command executables, if applicable.""" alias = self.alias if alias is None: pass elif callable(alias): self.cmd.pop(0) return else: self.cmd = alias + self.cmd[1:] # resolve any redirects the aliases may have applied self.redirect_leading() self.redirect_trailing() if self.binary_loc is None: return try: self.cmd = get_script_subproc_command(self.binary_loc, self.cmd[1:]) except PermissionError: e = "xonsh: subprocess mode: permission denied: {0}" raise XonshError(e.format(self.cmd[0]))
def partial_eval_alias(f, acc_args=()): """Dispatches the appropriate eval alias based on the number of args to the original callable alias and how many arguments to apply. """ # no partial needed if no extra args if not acc_args: return f # need to dispatch numargs = 0 for name, param in inspect.signature(f).parameters.items(): if (param.kind == param.POSITIONAL_ONLY or param.kind == param.POSITIONAL_OR_KEYWORD): numargs += 1 elif name in ALIAS_KWARG_NAMES and param.kind == param.KEYWORD_ONLY: numargs += 1 if numargs < 7: return PARTIAL_EVAL_ALIASES[numargs](f, acc_args=acc_args) else: e = "Expected proxy with 6 or fewer arguments for {}, not {}" raise XonshError(e.format(", ".join(ALIAS_KWARG_NAMES), numargs))
def stderr(self, value): isout = builtins.__xonsh__.env.get("MERGE_STDERR") multi_redir = False if isout: if self._stdout is None: self._stdout = value elif value is None: pass else: multi_redir = True else: if self._stderr is None: self._stderr = value elif value is None: pass else: multi_redir = True if multi_redir: safe_close(value) msg = "Multiple redirections for stderr for {0!r}" msg = msg.format(" ".join(self.args)) raise XonshError(msg)
def run_subproc(cmds, captured=True): """Runs a subprocess, in its many forms. This takes a list of 'commands,' which may be a list of command line arguments or a string, representing a special connecting character. For example:: $ ls | grep wakka is represented by the following cmds:: [['ls'], '|', ['grep', 'wakka']] Lastly, the captured argument affects only the last real command. """ global ENV background = False if cmds[-1] == '&': background = True cmds = cmds[:-1] write_target = None last_cmd = len(cmds) - 1 prev = None procs = [] prev_proc = None for ix, cmd in enumerate(cmds): stdin = None stdout = None stderr = None if isinstance(cmd, string_types): prev = cmd continue streams = {} while True: if len(cmd) >= 3 and _is_redirect(cmd[-2]): _redirect_io(streams, cmd[-2], cmd[-1]) cmd = cmd[:-2] elif len(cmd) >= 2 and _is_redirect(cmd[-1]): _redirect_io(streams, cmd[-1]) cmd = cmd[:-1] elif len(cmd) >= 3 and cmd[0] == '<': _redirect_io(streams, cmd[0], cmd[1]) cmd = cmd[2:] else: break # set standard input if 'stdin' in streams: if prev_proc is not None: raise XonshError('Multiple inputs for stdin') stdin = streams['stdin'] elif prev_proc is not None: stdin = prev_proc.stdout # set standard output if 'stdout' in streams: if ix != last_cmd: raise XonshError('Multiple redirects for stdout') stdout = streams['stdout'] elif captured or ix != last_cmd: stdout = PIPE else: stdout = None # set standard error if 'stderr' in streams: stderr = streams['stderr'] uninew = ix == last_cmd alias = builtins.aliases.get(cmd[0], None) if callable(alias): aliased_cmd = alias else: if alias is not None: cmd = alias + cmd[1:] n = _get_runnable_name(cmd[0]) if n is None: aliased_cmd = cmd else: try: aliased_cmd = get_script_subproc_command(n, cmd[1:]) except PermissionError: e = 'xonsh: subprocess mode: permission denied: {0}' raise XonshError(e.format(cmd[0])) if callable(aliased_cmd): prev_is_proxy = True numargs = len(inspect.signature(aliased_cmd).parameters) if numargs == 2: cls = SimpleProcProxy elif numargs == 4: cls = ProcProxy else: e = 'Expected callable with 2 or 4 arguments, not {}' raise XonshError(e.format(numargs)) proc = cls(aliased_cmd, cmd[1:], stdin, stdout, stderr, universal_newlines=uninew) else: prev_is_proxy = False subproc_kwargs = {} if ON_POSIX: subproc_kwargs['preexec_fn'] = _subproc_pre try: proc = Popen(aliased_cmd, universal_newlines=uninew, env=ENV.detype(), stdin=stdin, stdout=stdout, stderr=stderr, **subproc_kwargs) except PermissionError: e = 'xonsh: subprocess mode: permission denied: {0}' raise XonshError(e.format(aliased_cmd[0])) except FileNotFoundError: cmd = aliased_cmd[0] e = 'xonsh: subprocess mode: command not found: {0}'.format( cmd) sug = suggest_commands(cmd, ENV, builtins.aliases) if len(sug.strip()) > 0: e += '\n' + suggest_commands(cmd, ENV, builtins.aliases) raise XonshError(e) procs.append(proc) prev = None prev_proc = proc for proc in procs[:-1]: try: proc.stdout.close() except OSError: pass if not prev_is_proxy: add_job({ 'cmds': cmds, 'pids': [i.pid for i in procs], 'obj': prev_proc, 'bg': background }) if background: return if prev_is_proxy: prev_proc.wait() wait_for_active_job() if write_target is None: # get output output = '' if prev_proc.stdout not in (None, sys.stdout): output = prev_proc.stdout.read() if captured: return output elif last_stdout not in (PIPE, None, sys.stdout): last_stdout.close()