def resolve_binary_loc(self): """Sets the binary location""" alias = self.alias if alias is None: binary_loc = locate_binary(self.cmd[0]) elif callable(alias): binary_loc = None else: binary_loc = locate_binary(alias[0]) self.binary_loc = binary_loc
def resolve_binary_loc(self): """Sets the binary location""" alias = self.alias if alias is None: cmd0 = self.cmd[0] binary_loc = xenv.locate_binary(cmd0) if binary_loc == cmd0 and cmd0 in self.alias_stack: raise Exception(f'Recursive calls to "{cmd0}" alias.') elif callable(alias): binary_loc = None else: binary_loc = xenv.locate_binary(alias[0]) self.binary_loc = binary_loc
def test_locate_binary_on_windows(): files = ('file1.exe', 'FILE2.BAT', 'file3.txt') with TemporaryDirectory() as tmpdir: for fname in files: fpath = os.path.join(tmpdir, fname) with open(fpath, 'w') as f: f.write(fpath) env = Env({'PATH': [tmpdir], 'PATHEXT': ['.COM', '.EXE', '.BAT']}) with mock_xonsh_env(env): assert_equal( locate_binary('file1'), os.path.join(tmpdir,'file1.exe')) assert_equal( locate_binary('file1.exe'), os.path.join(tmpdir,'file1.exe')) assert_equal( locate_binary('file2'), os.path.join(tmpdir,'FILE2.BAT')) assert_equal( locate_binary('file2.bat'), os.path.join(tmpdir,'FILE2.BAT')) assert_equal( locate_binary('file3'), None)
def source_alias(args, stdin=None): """Executes the contents of the provided files in the current context. If sourced file isn't found in cwd, search for file along $PATH to source instead. """ env = builtins.__xonsh_env__ encoding = env.get('XONSH_ENCODING') errors = env.get('XONSH_ENCODING_ERRORS') for i, fname in enumerate(args): fpath = fname if not os.path.isfile(fpath): fpath = locate_binary(fname) if fpath is None: if env.get('XONSH_DEBUG'): print('source: {}: No such file'.format(fname), file=sys.stderr) if i == 0: raise RuntimeError('must source at least one file, ' + fname + 'does not exist.') break with open(fpath, 'r', encoding=encoding, errors=errors) as fp: src = fp.read() if not src.endswith('\n'): src += '\n' ctx = builtins.__xonsh_ctx__ updates = {'__file__': fpath, '__name__': os.path.abspath(fpath)} with env.swap(ARGS=args[i+1:]), swap_values(ctx, updates): builtins.execx(src, 'exec', ctx, filename=fpath)
def test_locate_binary_on_windows(xonsh_builtins): files = ("file1.exe", "FILE2.BAT", "file3.txt") with TemporaryDirectory() as tmpdir: for fname in files: fpath = os.path.join(tmpdir, fname) with open(fpath, "w") as f: f.write(fpath) xonsh_builtins.__xonsh__.env.update( {"PATH": [tmpdir], "PATHEXT": [".COM", ".EXE", ".BAT"]} ) xonsh_builtins.__xonsh__.commands_cache = CommandsCache() assert locate_binary("file1") == os.path.join(tmpdir, "file1.exe") assert locate_binary("file1.exe") == os.path.join(tmpdir, "file1.exe") assert locate_binary("file2") == os.path.join(tmpdir, "FILE2.BAT") assert locate_binary("file2.bat") == os.path.join(tmpdir, "FILE2.BAT") assert locate_binary("file3") is None
def test_locate_binary_on_windows(xonsh_builtins): files = ('file1.exe', 'FILE2.BAT', 'file3.txt') with TemporaryDirectory() as tmpdir: for fname in files: fpath = os.path.join(tmpdir, fname) with open(fpath, 'w') as f: f.write(fpath) xonsh_builtins.__xonsh_env__.update({ 'PATH': [tmpdir], 'PATHEXT': ['.COM', '.EXE', '.BAT'], }) assert locate_binary('file1') == os.path.join(tmpdir, 'file1.exe') assert locate_binary('file1.exe') == os.path.join(tmpdir, 'file1.exe') assert locate_binary('file2') == os.path.join(tmpdir, 'FILE2.BAT') assert locate_binary('file2.bat') == os.path.join(tmpdir, 'FILE2.BAT') assert locate_binary('file3') is None
def source_alias(args, stdin=None): """Executes the contents of the provided files in the current context. If sourced file isn't found in cwd, search for file along $PATH to source instead. """ env = builtins.__xonsh_env__ encoding = env.get('XONSH_ENCODING') errors = env.get('XONSH_ENCODING_ERRORS') for i, fname in enumerate(args): fpath = fname if not os.path.isfile(fpath): fpath = locate_binary(fname) if fpath is None: if env.get('XONSH_DEBUG'): print('source: {}: No such file'.format(fname), file=sys.stderr) if i == 0: raise RuntimeError('must source at least one file, ' + fname + 'does not exist.') break with open(fpath, 'r', encoding=encoding, errors=errors) as fp: src = fp.read() if not src.endswith('\n'): src += '\n' ctx = builtins.__xonsh_ctx__ updates = {'__file__': fpath, '__name__': os.path.abspath(fpath)} with env.swap(ARGS=args[i + 1:]), swap_values(ctx, updates): builtins.execx(src, 'exec', ctx, filename=fpath)
def test_locate_binary_on_windows(xonsh_builtins): files = ('file1.exe', 'FILE2.BAT', 'file3.txt') with TemporaryDirectory() as tmpdir: for fname in files: fpath = os.path.join(tmpdir, fname) with open(fpath, 'w') as f: f.write(fpath) xonsh_builtins.__xonsh_env__.update({ 'PATH': [tmpdir], 'PATHEXT': ['.COM', '.EXE', '.BAT'], }) assert locate_binary('file1') == os.path.join(tmpdir,'file1.exe') assert locate_binary('file1.exe') == os.path.join(tmpdir,'file1.exe') assert locate_binary('file2') == os.path.join(tmpdir,'FILE2.BAT') assert locate_binary('file2.bat') == os.path.join(tmpdir,'FILE2.BAT') assert locate_binary('file3') is None
def source_alias(args, stdin=None): """Executes the contents of the provided files in the current context. If sourced file isn't found in cwd, search for file along $PATH to source instead""" for fname in args: if not os.path.isfile(fname): fname = locate_binary(fname, cwd=None)[:-1] with open(fname, 'r') as fp: execx(fp.read(), 'exec', builtins.__xonsh_ctx__)
def test_locate_binary_on_windows(xession): files = ("file1.exe", "FILE2.BAT", "file3.txt") with TemporaryDirectory() as tmpdir: tmpdir = os.path.realpath(tmpdir) for fname in files: fpath = os.path.join(tmpdir, fname) with open(fpath, "w") as f: f.write(fpath) xession.env.update({ "PATH": [tmpdir], "PATHEXT": [".COM", ".EXE", ".BAT"] }) assert locate_binary("file1") == os.path.join(tmpdir, "file1.exe") assert locate_binary("file1.exe") == os.path.join(tmpdir, "file1.exe") assert locate_binary("file2") == os.path.join(tmpdir, "FILE2.BAT") assert locate_binary("file2.bat") == os.path.join(tmpdir, "FILE2.BAT") assert locate_binary("file3") is None
def source_alias(args, stdin=None): """Executes the contents of the provided files in the current context. If sourced file isn't found in cwd, search for file along $PATH to source instead. """ env = builtins.__xonsh_env__ encoding = env.get('XONSH_ENCODING') errors = env.get('XONSH_ENCODING_ERRORS') for fname in args: if not os.path.isfile(fname): fname = locate_binary(fname) with open(fname, 'r', encoding=encoding, errors=errors) as fp: builtins.execx(fp.read(), 'exec', builtins.__xonsh_ctx__)
def sudo(args, sdin=None): if len(args) < 1: print("You need to provide an executable to run as " "Administrator.") return cmd = args[0] if locate_binary(cmd): return winutils.sudo(cmd, args[1:]) elif cmd.lower() in windows_cmd_aliases: args = ["/D", "/C", "CD", _get_cwd(), "&&"] + args return winutils.sudo("cmd", args) else: msg = 'Cannot find the path for executable "{0}".' print(msg.format(cmd))
def sudo(args, sdin=None): if len(args) < 1: print('You need to provide an executable to run as ' 'Administrator.') return cmd = args[0] if locate_binary(cmd): return winutils.sudo(cmd, args[1:]) elif cmd.lower() in windows_cmd_aliases: args = ['/D', '/C', 'CD', _get_cwd(), '&&'] + args return winutils.sudo('cmd', args) else: msg = 'Cannot find the path for executable "{0}".' print(msg.format(cmd))
def sudo(args): if len(args) < 1: print("You need to provide an executable to run as " "Administrator.") return cmd = args[0] if locate_binary(cmd): return winutils.sudo(cmd, args[1:]) elif cmd.lower() in windows_cmd_aliases: args = ["/D", "/C", "CD", _get_cwd(), "&&"] + args return winutils.sudo("cmd", args) else: msg = 'Cannot find the path for executable "{0}".' print(msg.format(cmd))
def source_alias(args, stdin=None): """Executes the contents of the provided files in the current context. If sourced file isn't found in cwd, search for file along $PATH to source instead. """ env = builtins.__xonsh_env__ encoding = env.get("XONSH_ENCODING") errors = env.get("XONSH_ENCODING_ERRORS") for fname in args: if not os.path.isfile(fname): fname = locate_binary(fname) with open(fname, "r", encoding=encoding, errors=errors) as fp: src = fp.read() if not src.endswith("\n"): src += "\n" builtins.execx(src, "exec", builtins.__xonsh_ctx__)
def source_alias(args, stdin=None): """Executes the contents of the provided files in the current context. If sourced file isn't found in cwd, search for file along $PATH to source instead. """ env = builtins.__xonsh_env__ encoding = env.get("XONSH_ENCODING") errors = env.get("XONSH_ENCODING_ERRORS") for i, fname in enumerate(args): fpath = fname if not os.path.isfile(fpath): fpath = locate_binary(fname) if fpath is None: if env.get("XONSH_DEBUG"): print("source: {}: No such file".format(fname), file=sys.stderr) if i == 0: raise RuntimeError("must source at least one file, " + fname + "does not exist.") break _, fext = os.path.splitext(fpath) if fext and fext != ".xsh" and fext != ".py": raise RuntimeError( "attempting to source non-xonsh file! If you are " "trying to source a file in another language, " "then please use the appropriate source command. " "For example, source-bash script.sh") with open(fpath, "r", encoding=encoding, errors=errors) as fp: src = fp.read() if not src.endswith("\n"): src += "\n" ctx = builtins.__xonsh_ctx__ updates = {"__file__": fpath, "__name__": os.path.abspath(fpath)} with env.swap(**make_args_env(args[i + 1:])), swap_values( ctx, updates): try: builtins.execx(src, "exec", ctx, filename=fpath) except Exception: print_color( "{RED}You may be attempting to source non-xonsh file! " "{NO_COLOR}If you are trying to source a file in " "another language, then please use the appropriate " "source command. For example, {GREEN}source-bash " "script.sh{NO_COLOR}", file=sys.stderr, ) raise
def source_alias(args, stdin=None): """Executes the contents of the provided files in the current context. If sourced file isn't found in cwd, search for file along $PATH to source instead. """ env = builtins.__xonsh__.env encoding = env.get("XONSH_ENCODING") errors = env.get("XONSH_ENCODING_ERRORS") for i, fname in enumerate(args): fpath = fname if not os.path.isfile(fpath): fpath = locate_binary(fname) if fpath is None: if env.get("XONSH_DEBUG"): print("source: {}: No such file".format(fname), file=sys.stderr) if i == 0: raise RuntimeError( "must source at least one file, " + fname + "does not exist." ) break _, fext = os.path.splitext(fpath) if fext and fext != ".xsh" and fext != ".py": raise RuntimeError( "attempting to source non-xonsh file! If you are " "trying to source a file in another language, " "then please use the appropriate source command. " "For example, source-bash script.sh" ) with open(fpath, "r", encoding=encoding, errors=errors) as fp: src = fp.read() if not src.endswith("\n"): src += "\n" ctx = builtins.__xonsh__.ctx updates = {"__file__": fpath, "__name__": os.path.abspath(fpath)} with env.swap(**make_args_env(args[i + 1 :])), swap_values(ctx, updates): try: builtins.execx(src, "exec", ctx, filename=fpath) except Exception: print_color( "{RED}You may be attempting to source non-xonsh file! " "{NO_COLOR}If you are trying to source a file in " "another language, then please use the appropriate " "source command. For example, {GREEN}source-bash " "script.sh{NO_COLOR}", file=sys.stderr, ) raise
def source_alias(args, stdin=None): """Executes the contents of the provided files in the current context. If sourced file isn't found in cwd, search for file along $PATH to source instead. """ env = builtins.__xonsh_env__ encoding = env.get('XONSH_ENCODING') errors = env.get('XONSH_ENCODING_ERRORS') for i, fname in enumerate(args): fpath = fname if not os.path.isfile(fpath): fpath = locate_binary(fname) if fpath is None: if env.get('XONSH_DEBUG'): print('source: {}: No such file'.format(fname), file=sys.stderr) if i == 0: raise RuntimeError('must source at least one file, ' + fname + 'does not exist.') break _, fext = os.path.splitext(fpath) if fext and fext != '.xsh' and fext != '.py': raise RuntimeError( 'attempting to source non-xonsh file! If you are ' 'trying to source a file in another language, ' 'then please use the appropriate source command. ' 'For example, source-bash script.sh') with open(fpath, 'r', encoding=encoding, errors=errors) as fp: src = fp.read() if not src.endswith('\n'): src += '\n' ctx = builtins.__xonsh_ctx__ updates = {'__file__': fpath, '__name__': os.path.abspath(fpath)} with env.swap(**make_args_env(args[i + 1:])), swap_values( ctx, updates): try: builtins.execx(src, 'exec', ctx, filename=fpath) except Exception: print_color( '{RED}You may be attempting to source non-xonsh file! ' '{NO_COLOR}If you are trying to source a file in ' 'another language, then please use the appropriate ' 'source command. For example, {GREEN}source-bash ' 'script.sh{NO_COLOR}', file=sys.stderr) raise
def source_cmd(args, stdin=None): """Simple cmd.exe-specific wrapper around source-foreign.""" args = list(args) fpath = locate_binary(args[0]) args[0] = fpath if fpath else args[0] if not os.path.isfile(args[0]): return (None, 'xonsh: error: File not found: {}\n'.format(args[0]), 1) prevcmd = 'call ' prevcmd += ' '.join([argvquote(arg, force=True) for arg in args]) prevcmd = escape_windows_cmd_string(prevcmd) args.append('--prevcmd={}'.format(prevcmd)) args.insert(0, 'cmd') args.append('--interactive=0') args.append('--sourcer=call') args.append('--envcmd=set') args.append('--seterrpostcmd=if errorlevel 1 exit 1') args.append('--use-tmpfile=1') return source_foreign(args, stdin=stdin)
def source_cmd(args, stdin=None): """Simple cmd.exe-specific wrapper around source-foreign.""" args = list(args) fpath = locate_binary(args[0]) args[0] = fpath if fpath else args[0] if not os.path.isfile(args[0]): return (None, "xonsh: error: File not found: {}\n".format(args[0]), 1) prevcmd = "call " prevcmd += " ".join([argvquote(arg, force=True) for arg in args]) prevcmd = escape_windows_cmd_string(prevcmd) args.append("--prevcmd={}".format(prevcmd)) args.insert(0, "cmd") args.append("--interactive=0") args.append("--sourcer=call") args.append("--envcmd=set") args.append("--seterrpostcmd=if errorlevel 1 exit 1") args.append("--use-tmpfile=1") with builtins.__xonsh_env__.swap(PROMPT="$P$G"): return source_foreign(args, stdin=stdin)
def source_cmd(args, stdin=None): """Simple cmd.exe-specific wrapper around source-foreign.""" args = list(args) fpath = locate_binary(args[0]) args[0] = fpath if fpath else args[0] if not os.path.isfile(args[0]): return (None, "xonsh: error: File not found: {}\n".format(args[0]), 1) prevcmd = "call " prevcmd += " ".join([argvquote(arg, force=True) for arg in args]) prevcmd = escape_windows_cmd_string(prevcmd) args.append("--prevcmd={}".format(prevcmd)) args.insert(0, "cmd") args.append("--interactive=0") args.append("--sourcer=call") args.append("--envcmd=set") args.append("--seterrpostcmd=if errorlevel 1 exit 1") args.append("--use-tmpfile=1") with builtins.__xonsh__.env.swap(PROMPT="$P$G"): return source_foreign(args, stdin=stdin)
def source_alias(args, stdin=None): """Executes the contents of the provided files in the current context. If sourced file isn't found in cwd, search for file along $PATH to source instead. """ env = builtins.__xonsh_env__ encoding = env.get('XONSH_ENCODING') errors = env.get('XONSH_ENCODING_ERRORS') for i, fname in enumerate(args): fpath = fname if not os.path.isfile(fpath): fpath = locate_binary(fname) if fpath is None: if env.get('XONSH_DEBUG'): print('source: {}: No such file'.format(fname), file=sys.stderr) if i == 0: raise RuntimeError('must source at least one file, ' + fname + 'does not exist.') break _, fext = os.path.splitext(fpath) if fext and fext != '.xsh' and fext != '.py': raise RuntimeError('attempting to source non-xonsh file! If you are ' 'trying to source a file in another language, ' 'then please use the appropriate source command. ' 'For example, source-bash script.sh') with open(fpath, 'r', encoding=encoding, errors=errors) as fp: src = fp.read() if not src.endswith('\n'): src += '\n' ctx = builtins.__xonsh_ctx__ updates = {'__file__': fpath, '__name__': os.path.abspath(fpath)} with env.swap(ARGS=args[i+1:]), swap_values(ctx, updates): try: builtins.execx(src, 'exec', ctx, filename=fpath) except Exception: print_color('{RED}You may be attempting to source non-xonsh file! ' '{NO_COLOR}If you are trying to source a file in ' 'another language, then please use the appropriate ' 'source command. For example, {GREEN}source-bash ' 'script.sh{NO_COLOR}', file=sys.stderr) raise
def make_default_aliases(): """Creates a new default aliases dictionary.""" default_aliases = { "cd": cd, "pushd": pushd, "popd": popd, "dirs": dirs, "jobs": jobs, "fg": fg, "bg": bg, "EOF": xonsh_exit, "exit": xonsh_exit, "quit": xonsh_exit, "exec": xexec, "xexec": xexec, "source": source_alias, "source-zsh": ["source-foreign", "zsh", "--sourcer=source"], "source-bash": ["source-foreign", "bash", "--sourcer=source"], "source-cmd": source_cmd, "source-foreign": source_foreign, "history": xhm.history_main, "replay": replay_main, "trace": trace, "timeit": timeit_alias, "xonfig": xonfig, "scp-resume": ["rsync", "--partial", "-h", "--progress", "--rsh=ssh"], "showcmd": showcmd, "ipynb": ["jupyter", "notebook", "--no-browser"], "which": xxw.which, "xontrib": xontribs_main, "completer": xca.completer_alias, "xpip": detect_xpip_alias(), "xonsh-reset": xonsh_reset, } if ON_WINDOWS: # Borrow builtin commands from cmd.exe. windows_cmd_aliases = { "cls", "copy", "del", "dir", "echo", "erase", "md", "mkdir", "mklink", "move", "rd", "ren", "rename", "rmdir", "time", "type", "vol", } for alias in windows_cmd_aliases: default_aliases[alias] = ["cmd", "/c", alias] default_aliases["call"] = ["source-cmd"] default_aliases["source-bat"] = ["source-cmd"] default_aliases["clear"] = "cls" if ON_ANACONDA: # Add aliases specific to the Anaconda python distribution. default_aliases["activate"] = ["source-cmd", "activate.bat"] default_aliases["deactivate"] = ["source-cmd", "deactivate.bat"] if not locate_binary("sudo"): import xonsh.winutils as winutils def sudo(args): if len(args) < 1: print("You need to provide an executable to run as " "Administrator.") return cmd = args[0] if locate_binary(cmd): return winutils.sudo(cmd, args[1:]) elif cmd.lower() in windows_cmd_aliases: args = ["/D", "/C", "CD", _get_cwd(), "&&"] + args return winutils.sudo("cmd", args) else: msg = 'Cannot find the path for executable "{0}".' print(msg.format(cmd)) default_aliases["sudo"] = sudo elif ON_DARWIN: default_aliases["ls"] = ["ls", "-G"] elif ON_FREEBSD: default_aliases["grep"] = ["grep", "--color=auto"] default_aliases["egrep"] = ["egrep", "--color=auto"] default_aliases["fgrep"] = ["fgrep", "--color=auto"] default_aliases["ls"] = ["ls", "-G"] elif ON_NETBSD: default_aliases["grep"] = ["grep", "--color=auto"] default_aliases["egrep"] = ["egrep", "--color=auto"] default_aliases["fgrep"] = ["fgrep", "--color=auto"] else: default_aliases["grep"] = ["grep", "--color=auto"] default_aliases["egrep"] = ["egrep", "--color=auto"] default_aliases["fgrep"] = ["fgrep", "--color=auto"] default_aliases["ls"] = ["ls", "--color=auto", "-v"] return default_aliases
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 procs = [] prev_proc = None for ix, cmd in enumerate(cmds): stdin = None stderr = None if isinstance(cmd, string_types): 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) and (not captured) alias = builtins.aliases.get(cmd[0], None) if (alias is None and builtins.__xonsh_env__.get('AUTO_CD') and len(cmd) == 1 and os.path.isdir(cmd[0]) and locate_binary(cmd[0], cwd=None) is None): cmd.insert(0, 'cd') alias = builtins.aliases.get('cd', 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 usetee = (stdout is None) and (not background) and \ ENV.get('XONSH_STORE_STDOUT', False) cls = TeePTYProc if usetee else Popen subproc_kwargs = {} if ON_POSIX and cls is Popen: subproc_kwargs['preexec_fn'] = _subproc_pre try: proc = cls(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_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 ENV.get('XONSH_INTERACTIVE') and not ENV.get('XONSH_STORE_STDOUT'): # set title here to get current command running try: builtins.__xonsh_shell__.settitle() except AttributeError: pass if background: return if prev_is_proxy: prev_proc.wait() wait_for_active_job() hist = builtins.__xonsh_history__ hist.last_cmd_rtn = prev_proc.returncode if write_target is None: # get output output = b'' if prev_proc.stdout not in (None, sys.stdout): output = prev_proc.stdout.read() if captured: # to get proper encoding from Popen, we have to # use a byte stream and then implement universal_newlines here output = output.decode(encoding=ENV.get('XONSH_ENCODING'), errors=ENV.get('XONSH_ENCODING_ERRORS')) output = output.replace('\r\n', '\n') return output else: hist.last_cmd_out = output
def run_subproc(cmds, captured=False): """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 procinfo = {} if cmds[-1] == '&': background = True cmds = cmds[:-1] write_target = None last_cmd = len(cmds) - 1 procs = [] prev_proc = None _capture_streams = captured in {'stdout', 'object'} for ix, cmd in enumerate(cmds): starttime = time.time() procinfo['args'] = list(cmd) stdin = None stderr = None if isinstance(cmd, str): 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'][-1] procinfo['stdin_redirect'] = streams['stdin'][:-1] elif prev_proc is not None: stdin = prev_proc.stdout # set standard output _stdout_name = None _stderr_name = None if 'stdout' in streams: if ix != last_cmd: raise XonshError('Multiple redirects for stdout') stdout = streams['stdout'][-1] procinfo['stdout_redirect'] = streams['stdout'][:-1] elif ix != last_cmd: stdout = PIPE elif _capture_streams: _nstdout = stdout = tempfile.NamedTemporaryFile(delete=False) _stdout_name = stdout.name elif builtins.__xonsh_stdout_uncaptured__ is not None: stdout = builtins.__xonsh_stdout_uncaptured__ else: stdout = None # set standard error if 'stderr' in streams: stderr = streams['stderr'][-1] procinfo['stderr_redirect'] = streams['stderr'][:-1] elif captured == 'object' and ix == last_cmd: _nstderr = stderr = tempfile.NamedTemporaryFile(delete=False) _stderr_name = stderr.name elif builtins.__xonsh_stderr_uncaptured__ is not None: stderr = builtins.__xonsh_stderr_uncaptured__ uninew = (ix == last_cmd) and (not _capture_streams) alias = builtins.aliases.get(cmd[0], None) procinfo['alias'] = alias if (alias is None and builtins.__xonsh_env__.get('AUTO_CD') and len(cmd) == 1 and os.path.isdir(cmd[0]) and locate_binary(cmd[0]) is None): cmd.insert(0, 'cd') alias = builtins.aliases.get('cd', None) if callable(alias): aliased_cmd = alias else: if alias is not None: cmd = alias + cmd[1:] n = locate_binary(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])) _stdin_file = None if (stdin is not None and ENV.get('XONSH_STORE_STDIN') and captured == 'object' and 'cat' in __xonsh_commands_cache__ and 'tee' in __xonsh_commands_cache__): _stdin_file = tempfile.NamedTemporaryFile() cproc = Popen(['cat'], stdin=stdin, stdout=PIPE) tproc = Popen(['tee', _stdin_file.name], stdin=cproc.stdout, stdout=PIPE) stdin = tproc.stdout if callable(aliased_cmd): prev_is_proxy = True bgable = getattr(aliased_cmd, '__xonsh_backgroundable__', True) numargs = len(inspect.signature(aliased_cmd).parameters) if numargs == 2: cls = SimpleProcProxy if bgable else SimpleForegroundProcProxy elif numargs == 4: cls = ProcProxy if bgable else ForegroundProcProxy 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 usetee = ((stdout is None) and (not background) and ENV.get('XONSH_STORE_STDOUT', False)) cls = TeePTYProc if usetee else Popen subproc_kwargs = {} if ON_POSIX and cls is Popen: subproc_kwargs['preexec_fn'] = _subproc_pre try: proc = cls(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_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 (ENV.get('XONSH_INTERACTIVE') and not ENV.get('XONSH_STORE_STDOUT') and not _capture_streams): # set title here to get current command running try: builtins.__xonsh_shell__.settitle() except AttributeError: pass if background: return if prev_is_proxy: prev_proc.wait() wait_for_active_job() hist = builtins.__xonsh_history__ hist.last_cmd_rtn = prev_proc.returncode # get output output = b'' if write_target is None: if _stdout_name is not None: with open(_stdout_name, 'rb') as stdoutfile: output = stdoutfile.read() try: _nstdout.close() except: pass os.unlink(_stdout_name) elif prev_proc.stdout not in (None, sys.stdout): output = prev_proc.stdout.read() if _capture_streams: # to get proper encoding from Popen, we have to # use a byte stream and then implement universal_newlines here output = output.decode(encoding=ENV.get('XONSH_ENCODING'), errors=ENV.get('XONSH_ENCODING_ERRORS')) output = output.replace('\r\n', '\n') else: hist.last_cmd_out = output if captured == 'object': # get stderr as well named = _stderr_name is not None unnamed = prev_proc.stderr not in {None, sys.stderr} if named: with open(_stderr_name, 'rb') as stderrfile: errout = stderrfile.read() try: _nstderr.close() except: pass os.unlink(_stderr_name) elif unnamed: errout = prev_proc.stderr.read() if named or unnamed: errout = errout.decode(encoding=ENV.get('XONSH_ENCODING'), errors=ENV.get('XONSH_ENCODING_ERRORS')) errout = errout.replace('\r\n', '\n') procinfo['stderr'] = errout if getattr(prev_proc, 'signal', None): sig, core = prev_proc.signal sig_str = SIGNAL_MESSAGES.get(sig) if sig_str: if core: sig_str += ' (core dumped)' print(sig_str, file=sys.stderr) if (not prev_is_proxy and hist.last_cmd_rtn is not None and hist.last_cmd_rtn > 0 and ENV.get('RAISE_SUBPROC_ERROR')): raise CalledProcessError(hist.last_cmd_rtn, aliased_cmd, output=output) if captured == 'stdout': return output elif captured is not False: procinfo['executed_cmd'] = aliased_cmd procinfo['pid'] = prev_proc.pid procinfo['returncode'] = prev_proc.returncode procinfo['timestamp'] = (starttime, time.time()) if captured == 'object': procinfo['stdout'] = output if _stdin_file is not None: _stdin_file.seek(0) procinfo['stdin'] = _stdin_file.read().decode() _stdin_file.close() return CompletedCommand(**procinfo) else: return HiddenCompletedCommand(**procinfo)
def source_cmd_fn( files: Annotated[tp.List[str], Arg(nargs="+")], login=False, aliascmd=None, extra_args="", safe=True, postcmd="", funcscmd="", seterrprevcmd=None, overwrite_aliases=False, suppress_skip_message=False, show=False, dryrun=False, _stderr=None, ): """ Source cmd.exe files Parameters ---------- files paths to source files. login : -l, --login whether the sourced shell should be login envcmd : --envcmd command to print environment aliascmd : --aliascmd command to print aliases extra_args : --extra-args extra arguments needed to run the shell safe : -s, --safe whether the source shell should be run safely, and not raise any errors, even if they occur. postcmd : --postcmd command(s) to run after all other commands funcscmd : --funcscmd code to find locations of all native functions in the shell language. seterrprevcmd : --seterrprevcmd command(s) to set exit-on-error before any other commands. overwrite_aliases : --overwrite-aliases flag for whether or not sourced aliases should replace the current xonsh aliases. suppress_skip_message : --suppress-skip-message flag for whether or not skip messages should be suppressed. show : --show show the script output. dryrun : -d, --dry-run Will not actually source the file. """ args = list(files) fpath = locate_binary(args[0]) args[0] = fpath if fpath else args[0] if not os.path.isfile(args[0]): return (None, f"xonsh: error: File not found: {args[0]}\n", 1) prevcmd = "call " prevcmd += " ".join([argvquote(arg, force=True) for arg in args]) prevcmd = escape_windows_cmd_string(prevcmd) with XSH.env.swap(PROMPT="$P$G"): return source_foreign_fn( shell="cmd", files_or_code=args, interactive=True, sourcer="call", envcmd="set", seterrpostcmd="if errorlevel 1 exit 1", use_tmpfile=True, prevcmd=prevcmd, # from this function login=login, aliascmd=aliascmd, extra_args=extra_args, safe=safe, postcmd=postcmd, funcscmd=funcscmd, seterrprevcmd=seterrprevcmd, overwrite_aliases=overwrite_aliases, suppress_skip_message=suppress_skip_message, show=show, dryrun=dryrun, )
def make_default_aliases(): """Creates a new default aliases dictionary.""" default_aliases = { "cd": cd, "pushd": pushd, "popd": popd, "dirs": dirs, "jobs": jobs, "fg": fg, "bg": bg, "EOF": xonsh_exit, "exit": xonsh_exit, "quit": xonsh_exit, "exec": xexec, "xexec": xexec, "source": source_alias, "source-zsh": ["source-foreign", "zsh", "--sourcer=source"], "source-bash": ["source-foreign", "bash", "--sourcer=source"], "source-cmd": source_cmd, "source-foreign": source_foreign, "history": xhm.history_main, "replay": replay_main, "trace": trace, "timeit": timeit_alias, "xonfig": xonfig, "scp-resume": ["rsync", "--partial", "-h", "--progress", "--rsh=ssh"], "showcmd": showcmd, "ipynb": ["jupyter", "notebook", "--no-browser"], "which": xxw.which, "xontrib": xontribs_main, "completer": xca.completer_alias, "xpip": detect_xpip_alias(), "xonsh-reset": xonsh_reset, } if ON_WINDOWS: # Borrow builtin commands from cmd.exe. windows_cmd_aliases = { "cls", "copy", "del", "dir", "echo", "erase", "md", "mkdir", "mklink", "move", "rd", "ren", "rename", "rmdir", "time", "type", "vol", } for alias in windows_cmd_aliases: default_aliases[alias] = ["cmd", "/c", alias] default_aliases["call"] = ["source-cmd"] default_aliases["source-bat"] = ["source-cmd"] default_aliases["clear"] = "cls" if ON_ANACONDA: # Add aliases specific to the Anaconda python distribution. default_aliases["activate"] = ["source-cmd", "activate.bat"] default_aliases["deactivate"] = ["source-cmd", "deactivate.bat"] if not locate_binary("sudo"): import xonsh.winutils as winutils def sudo(args): if len(args) < 1: print( "You need to provide an executable to run as " "Administrator." ) return cmd = args[0] if locate_binary(cmd): return winutils.sudo(cmd, args[1:]) elif cmd.lower() in windows_cmd_aliases: args = ["/D", "/C", "CD", _get_cwd(), "&&"] + args return winutils.sudo("cmd", args) else: msg = 'Cannot find the path for executable "{0}".' print(msg.format(cmd)) default_aliases["sudo"] = sudo elif ON_DARWIN: default_aliases["ls"] = ["ls", "-G"] elif ON_FREEBSD or ON_DRAGONFLY: default_aliases["grep"] = ["grep", "--color=auto"] default_aliases["egrep"] = ["egrep", "--color=auto"] default_aliases["fgrep"] = ["fgrep", "--color=auto"] default_aliases["ls"] = ["ls", "-G"] elif ON_NETBSD: default_aliases["grep"] = ["grep", "--color=auto"] default_aliases["egrep"] = ["egrep", "--color=auto"] default_aliases["fgrep"] = ["fgrep", "--color=auto"] else: default_aliases["grep"] = ["grep", "--color=auto"] default_aliases["egrep"] = ["egrep", "--color=auto"] default_aliases["fgrep"] = ["fgrep", "--color=auto"] default_aliases["ls"] = ["ls", "--color=auto", "-v"] return default_aliases
def make_default_aliases(): """Creates a new default aliases dictionary.""" default_aliases = { 'cd': cd, 'pushd': pushd, 'popd': popd, 'dirs': dirs, 'jobs': jobs, 'fg': fg, 'bg': bg, 'EOF': xonsh_exit, 'exit': xonsh_exit, 'quit': xonsh_exit, 'xexec': xexec, 'source': source_alias, 'source-zsh': ['source-foreign', 'zsh', '--sourcer=source'], 'source-bash': ['source-foreign', 'bash', '--sourcer=source'], 'source-cmd': source_cmd, 'source-foreign': source_foreign, 'history': history_main, 'replay': replay_main, '!!': bang_bang, '!n': bang_n, 'trace': trace, 'timeit': timeit_alias, 'xonfig': xonfig, 'scp-resume': ['rsync', '--partial', '-h', '--progress', '--rsh=ssh'], 'showcmd': showcmd, 'ipynb': ['jupyter', 'notebook', '--no-browser'], 'vox': vox, 'which': which, 'xontrib': xontribs_main, 'completer': completer_alias } if ON_WINDOWS: # Borrow builtin commands from cmd.exe. windows_cmd_aliases = { 'cls', 'copy', 'del', 'dir', 'erase', 'md', 'mkdir', 'mklink', 'move', 'rd', 'ren', 'rename', 'rmdir', 'time', 'type', 'vol' } for alias in windows_cmd_aliases: default_aliases[alias] = ['cmd', '/c', alias] default_aliases['call'] = ['source-cmd'] default_aliases['source-bat'] = ['source-cmd'] default_aliases['clear'] = 'cls' if ON_ANACONDA: # Add aliases specific to the Anaconda python distribution. default_aliases['activate'] = ['source-cmd', 'activate.bat'] default_aliases['deactivate'] = ['source-cmd', 'deactivate.bat'] if not locate_binary('sudo'): import xonsh.winutils as winutils def sudo(args, sdin=None): if len(args) < 1: print('You need to provide an executable to run as ' 'Administrator.') return cmd = args[0] if locate_binary(cmd): return winutils.sudo(cmd, args[1:]) elif cmd.lower() in windows_cmd_aliases: args = ['/D', '/C', 'CD', _get_cwd(), '&&'] + args return winutils.sudo('cmd', args) else: msg = 'Cannot find the path for executable "{0}".' print(msg.format(cmd)) default_aliases['sudo'] = sudo elif ON_DARWIN: default_aliases['ls'] = ['ls', '-G'] else: default_aliases['grep'] = ['grep', '--color=auto'] default_aliases['egrep'] = ['egrep', '--color=auto'] default_aliases['fgrep'] = ['fgrep', '--color=auto'] default_aliases['ls'] = ['ls', '--color=auto', '-v'] return default_aliases
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) and (not captured) alias = builtins.aliases.get(cmd[0], None) if (alias is None and builtins.__xonsh_env__.get('AUTO_CD') and len(cmds)==1 and os.path.isdir(cmd[0]) and locate_binary(cmd[0], cwd=None) is None): cmd.insert(0, 'cd') alias = builtins.aliases.get('cd', 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 usetee = (stdout is None) and (not background) and \ ENV.get('XONSH_STORE_STDOUT', False) cls = TeePTYProc if usetee else Popen subproc_kwargs = {} if ON_POSIX and cls is Popen: subproc_kwargs['preexec_fn'] = _subproc_pre try: proc = cls(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() hist = builtins.__xonsh_history__ hist.last_cmd_rtn = prev_proc.returncode if write_target is None: # get output output = '' if prev_proc.stdout not in (None, sys.stdout): output = prev_proc.stdout.read() if captured: # to get proper encoding from Popen, we have to # use a byte stream and then implement universal_newlines here output = output.decode(encoding=ENV.get('XONSH_ENCODING'), errors=ENV.get('XONSH_ENCODING_ERRORS')) output = output.replace('\r\n', '\n') return output else: hist.last_cmd_out = output
def run_subproc(cmds, captured=False): """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. """ env = builtins.__xonsh_env__ background = False procinfo = {} if cmds[-1] == '&': background = True cmds = cmds[:-1] _pipeline_group = None write_target = None last_cmd = len(cmds) - 1 procs = [] prev_proc = None _capture_streams = captured in {'stdout', 'object'} for ix, cmd in enumerate(cmds): starttime = time.time() procinfo['args'] = list(cmd) stdin = None stderr = None if isinstance(cmd, str): 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'][-1] procinfo['stdin_redirect'] = streams['stdin'][:-1] elif prev_proc is not None: stdin = prev_proc.stdout # set standard output _stdout_name = None _stderr_name = None if 'stdout' in streams: if ix != last_cmd: raise XonshError('Multiple redirects for stdout') stdout = streams['stdout'][-1] procinfo['stdout_redirect'] = streams['stdout'][:-1] elif ix != last_cmd: stdout = subprocess.PIPE elif _capture_streams: _nstdout = stdout = tempfile.NamedTemporaryFile(delete=False) _stdout_name = stdout.name elif builtins.__xonsh_stdout_uncaptured__ is not None: stdout = builtins.__xonsh_stdout_uncaptured__ else: stdout = None # set standard error if 'stderr' in streams: stderr = streams['stderr'][-1] procinfo['stderr_redirect'] = streams['stderr'][:-1] elif captured == 'object' and ix == last_cmd: _nstderr = stderr = tempfile.NamedTemporaryFile(delete=False) _stderr_name = stderr.name elif builtins.__xonsh_stderr_uncaptured__ is not None: stderr = builtins.__xonsh_stderr_uncaptured__ uninew = (ix == last_cmd) and (not _capture_streams) # find alias if callable(cmd[0]): alias = cmd[0] else: alias = builtins.aliases.get(cmd[0], None) procinfo['alias'] = alias # find binary location, if not callable if alias is None: binary_loc = locate_binary(cmd[0]) elif not callable(alias): binary_loc = locate_binary(alias[0]) # implement AUTO_CD if (alias is None and builtins.__xonsh_env__.get('AUTO_CD') and len(cmd) == 1 and os.path.isdir(cmd[0]) and binary_loc is None): cmd.insert(0, 'cd') alias = builtins.aliases.get('cd', None) if callable(alias): aliased_cmd = alias else: if alias is not None: aliased_cmd = alias + cmd[1:] else: aliased_cmd = cmd if binary_loc is not None: try: aliased_cmd = get_script_subproc_command(binary_loc, aliased_cmd[1:]) except PermissionError: e = 'xonsh: subprocess mode: permission denied: {0}' raise XonshError(e.format(cmd[0])) _stdin_file = None if (stdin is not None and env.get('XONSH_STORE_STDIN') and captured == 'object' and __xonsh_commands_cache__.lazy_locate_binary('cat') and __xonsh_commands_cache__.lazy_locate_binary('tee')): _stdin_file = tempfile.NamedTemporaryFile() cproc = subprocess.Popen(['cat'], stdin=stdin, stdout=subprocess.PIPE) tproc = subprocess.Popen(['tee', _stdin_file.name], stdin=cproc.stdout, stdout=subprocess.PIPE) stdin = tproc.stdout if callable(aliased_cmd): prev_is_proxy = True bgable = getattr(aliased_cmd, '__xonsh_backgroundable__', True) numargs = len(inspect.signature(aliased_cmd).parameters) if numargs == 2: cls = SimpleProcProxy if bgable else SimpleForegroundProcProxy elif numargs == 4: cls = ProcProxy if bgable else ForegroundProcProxy 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 usetee = ((stdout is None) and (not background) and env.get('XONSH_STORE_STDOUT', False)) cls = TeePTYProc if usetee else subprocess.Popen subproc_kwargs = {} if ON_POSIX and cls is subprocess.Popen: def _subproc_pre(): if _pipeline_group is None: os.setpgrp() else: os.setpgid(0, _pipeline_group) signal.signal(signal.SIGTSTP, lambda n, f: signal.pause()) subproc_kwargs['preexec_fn'] = _subproc_pre denv = env.detype() if ON_WINDOWS: # Over write prompt variable as xonsh's $PROMPT does # not make much sense for other subprocs denv['PROMPT'] = '$P$G' try: proc = cls(aliased_cmd, universal_newlines=uninew, env=denv, 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_proc = proc if ON_POSIX and cls is subprocess.Popen and _pipeline_group is None: _pipeline_group = prev_proc.pid if not prev_is_proxy: add_job({ 'cmds': cmds, 'pids': [i.pid for i in procs], 'obj': prev_proc, 'bg': background }) if (env.get('XONSH_INTERACTIVE') and not env.get('XONSH_STORE_STDOUT') and not _capture_streams): # set title here to get current command running try: builtins.__xonsh_shell__.settitle() except AttributeError: pass if background: return if prev_is_proxy: prev_proc.wait() wait_for_active_job() for proc in procs[:-1]: try: proc.stdout.close() except OSError: pass hist = builtins.__xonsh_history__ hist.last_cmd_rtn = prev_proc.returncode # get output output = b'' if write_target is None: if _stdout_name is not None: with open(_stdout_name, 'rb') as stdoutfile: output = stdoutfile.read() try: _nstdout.close() except Exception: pass os.unlink(_stdout_name) elif prev_proc.stdout not in (None, sys.stdout): output = prev_proc.stdout.read() if _capture_streams: # to get proper encoding from Popen, we have to # use a byte stream and then implement universal_newlines here output = output.decode(encoding=env.get('XONSH_ENCODING'), errors=env.get('XONSH_ENCODING_ERRORS')) output = output.replace('\r\n', '\n') else: hist.last_cmd_out = output if captured == 'object': # get stderr as well named = _stderr_name is not None unnamed = prev_proc.stderr not in {None, sys.stderr} if named: with open(_stderr_name, 'rb') as stderrfile: errout = stderrfile.read() try: _nstderr.close() except Exception: pass os.unlink(_stderr_name) elif unnamed: errout = prev_proc.stderr.read() if named or unnamed: errout = errout.decode(encoding=env.get('XONSH_ENCODING'), errors=env.get('XONSH_ENCODING_ERRORS')) errout = errout.replace('\r\n', '\n') procinfo['stderr'] = errout if getattr(prev_proc, 'signal', None): sig, core = prev_proc.signal sig_str = SIGNAL_MESSAGES.get(sig) if sig_str: if core: sig_str += ' (core dumped)' print(sig_str, file=sys.stderr) if (not prev_is_proxy and hist.last_cmd_rtn is not None and hist.last_cmd_rtn > 0 and env.get('RAISE_SUBPROC_ERROR')): raise subprocess.CalledProcessError(hist.last_cmd_rtn, aliased_cmd, output=output) if captured == 'stdout': return output elif captured is not False: procinfo['executed_cmd'] = aliased_cmd procinfo['pid'] = prev_proc.pid procinfo['returncode'] = prev_proc.returncode procinfo['timestamp'] = (starttime, time.time()) if captured == 'object': procinfo['stdout'] = output if _stdin_file is not None: _stdin_file.seek(0) procinfo['stdin'] = _stdin_file.read().decode() _stdin_file.close() return CompletedCommand(**procinfo) else: return HiddenCompletedCommand(**procinfo)