Esempio n. 1
0
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
Esempio n. 2
0
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))
Esempio n. 3
0
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))
Esempio n. 4
0
 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
Esempio n. 5
0
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)
Esempio n. 6
0
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
Esempio n. 7
0
    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']))
Esempio n. 8
0
 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
Esempio n. 9
0
 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
Esempio n. 10
0
 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
Esempio n. 11
0
    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
Esempio n. 12
0
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))
Esempio n. 13
0
 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()
Esempio n. 14
0
 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)
Esempio n. 15
0
 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)
Esempio n. 16
0
 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)
Esempio n. 17
0
    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
Esempio n. 18
0
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
Esempio n. 19
0
 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
Esempio n. 20
0
 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
Esempio n. 21
0
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)
Esempio n. 22
0
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
Esempio n. 23
0
File: shell.py Progetto: minrk/xonsh
 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
Esempio n. 24
0
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
Esempio n. 25
0
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
Esempio n. 26
0
 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]))
Esempio n. 27
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]))
Esempio n. 28
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))
Esempio n. 29
0
 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)
Esempio n. 30
0
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()