Пример #1
0
    def get_syspaths(cls):
        if cls.syspaths is not None:
            return cls.syspaths

        if config.standard_system_paths:
            cls.syspaths = config.standard_system_paths
            return cls.syspaths

        # detect system paths using registry
        def gen_expected_regex(parts):
            whitespace = "[\s]+"
            return whitespace.join(parts)

        paths = []

        cmd = [
            "REG", "QUERY",
            "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment",
            "/v", "PATH"
        ]

        expected = gen_expected_regex([
            "HKEY_LOCAL_MACHINE\\\\SYSTEM\\\\CurrentControlSet\\\\Control\\\\Session Manager\\\\Environment",
            "PATH", "REG_(EXPAND_)?SZ", "(.*)"
        ])

        p = popen(cmd,
                  stdout=subprocess.PIPE,
                  stderr=subprocess.PIPE,
                  shell=True)
        out_, _ = p.communicate()
        out_ = out_.strip()

        if p.returncode == 0:
            match = re.match(expected, out_)
            if match:
                paths.extend(match.group(2).split(os.pathsep))

        cmd = ["REG", "QUERY", "HKCU\\Environment", "/v", "PATH"]

        expected = gen_expected_regex([
            "HKEY_CURRENT_USER\\\\Environment", "PATH", "REG_(EXPAND_)?SZ",
            "(.*)"
        ])

        p = popen(cmd,
                  stdout=subprocess.PIPE,
                  stderr=subprocess.PIPE,
                  shell=True)
        out_, _ = p.communicate()
        out_ = out_.strip()

        if p.returncode == 0:
            match = re.match(expected, out_)
            if match:
                paths.extend(match.group(2).split(os.pathsep))

        cls.syspaths = set([x for x in paths if x])
        return cls.syspaths
Пример #2
0
def exec_python(attr, src, executable="python"):
    """Runs a python subproc to calculate a package attribute.

    Args:
        attr (str): Name of package attribute being created.
        src (list of str): Python code to execute, will be converted into
            semicolon-delimited single line of code.

    Returns:
        str: Output of python process.
    """
    import subprocess

    if isinstance(src, basestring):
        src = [src]

    p = popen([executable, "-c", "; ".join(src)],
              stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out, err = p.communicate()

    if p.returncode:
        from rez.exceptions import InvalidPackageError
        raise InvalidPackageError(
            "Error determining package attribute '%s':\n%s" % (attr, err))

    return out.strip()
Пример #3
0
    def _physical_cores_from_lscpu(self):
        import subprocess
        try:
            p = popen(['lscpu'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        except (OSError, IOError):
            return None

        stdout, stderr = p.communicate()
        if p.returncode:
            return None

        data = self._parse_colon_table_to_dict(stdout)

        # lscpu gives output like this:
        #
        # CPU(s):                24
        # On-line CPU(s) list:   0-23
        # Thread(s) per core:    2
        # Core(s) per socket:    6
        # Socket(s):             2

        # we want to take sockets * cores, and ignore threads...

        # some versions of lscpu format the sockets line differently...
        sockets = data.get('Socket(s)', data.get('CPU socket(s)'))
        if not sockets:
            return None
        cores = data.get('Core(s) per socket')
        if not cores:
            return None
        return int(sockets) * int(cores)
Пример #4
0
    def _physical_cores_from_wmic(self):
        # windows
        import subprocess
        try:
            p = popen('wmic cpu get NumberOfCores /value'.split(),
                      stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        except (OSError, IOError):
            return None

        stdout, stderr = p.communicate()
        if p.returncode:
            return None

        # a Windows machine with 1 installed CPU will return "NumberOfCores=N" where N is
        # the number of physical cores on that CPU chip. If more than one CPU is installed
        # there will be one "NumberOfCores=N" line listed per actual CPU, so the sum of all
        # N is the number of physical cores in the machine: this will be exactly one half the
        # number of logical cores (ie from multiprocessing.cpu_count) if HyperThreading is
        # enabled on the CPU(s)
        result = re.findall(r'NumberOfCores=(\d+)', stdout.strip())

        if not result:
            # don't know what's wrong... should get back a result like:
            # NumberOfCores=2
            return None

        return sum(map(int, result))
Пример #5
0
    def _physical_cores_from_lscpu(self):
        import subprocess
        try:
            p = popen(['lscpu'],
                      stdout=subprocess.PIPE,
                      stderr=subprocess.PIPE)
        except (OSError, IOError):
            return None

        stdout, stderr = p.communicate()
        if p.returncode:
            return None

        data = self._parse_colon_table_to_dict(stdout)

        # lscpu gives output like this:
        #
        # CPU(s):                24
        # On-line CPU(s) list:   0-23
        # Thread(s) per core:    2
        # Core(s) per socket:    6
        # Socket(s):             2

        # we want to take sockets * cores, and ignore threads...

        # some versions of lscpu format the sockets line differently...
        sockets = data.get('Socket(s)', data.get('CPU socket(s)'))
        if not sockets:
            return None
        cores = data.get('Core(s) per socket')
        if not cores:
            return None
        return int(sockets) * int(cores)
Пример #6
0
    def _physical_cores_from_wmic(self):
        # windows
        import subprocess
        try:
            p = popen('wmic cpu get NumberOfCores /value'.split(),
                      stdout=subprocess.PIPE,
                      stderr=subprocess.PIPE)
        except (OSError, IOError):
            return None

        stdout, stderr = p.communicate()
        if p.returncode:
            return None

        # a Windows machine with 1 installed CPU will return "NumberOfCores=N" where N is
        # the number of physical cores on that CPU chip. If more than one CPU is installed
        # there will be one "NumberOfCores=N" line listed per actual CPU, so the sum of all
        # N is the number of physical cores in the machine: this will be exactly one half the
        # number of logical cores (ie from multiprocessing.cpu_count) if HyperThreading is
        # enabled on the CPU(s)
        result = re.findall(r'NumberOfCores=(\d+)', stdout.strip())

        if not result:
            # don't know what's wrong... should get back a result like:
            # NumberOfCores=2
            return None

        return sum(map(int, result))
    def get_syspaths(cls):
        if cls.syspaths is not None:
            return cls.syspaths

        if config.standard_system_paths:
            cls.syspaths = config.standard_system_paths
            return cls.syspaths

        # detect system paths using registry
        cmd = "cmd=`which %s`; unset PATH; $cmd %s 'echo __PATHS_ $PATH'" \
              % (cls.name(), cls.command_arg)
        p = popen(cmd,
                  stdout=subprocess.PIPE,
                  stderr=subprocess.PIPE,
                  shell=True)
        out_, err_ = p.communicate()
        if p.returncode:
            paths = []
        else:
            lines = out_.split('\n')
            line = [x for x in lines if "__PATHS_" in x.split()][0]
            paths = line.strip().split()[-1].split(os.pathsep)

        for path in os.defpath.split(os.path.pathsep):
            if path not in paths:
                paths.append(path)

        cls.syspaths = [x for x in paths if x]
        return cls.syspaths
Пример #8
0
    def get_syspaths(cls):
        if cls.syspaths is not None:
            return cls.syspaths

        if config.standard_system_paths:
            cls.syspaths = config.standard_system_paths
            return cls.syspaths

        # detect system paths using registry
        cmd = "cmd=`which %s`; unset PATH; $cmd %s 'echo __PATHS_ $PATH'" \
              % (cls.name(), cls.command_arg)
        p = popen(cmd, stdout=subprocess.PIPE,
                  stderr=subprocess.PIPE, shell=True)
        out_, err_ = p.communicate()
        if p.returncode:
            paths = []
        else:
            lines = out_.split('\n')
            line = [x for x in lines if "__PATHS_" in x.split()][0]
            paths = line.strip().split()[-1].split(os.pathsep)

        for path in os.defpath.split(os.path.pathsep):
            if path not in paths:
                paths.append(path)

        cls.syspaths = [x for x in paths if x]
        return cls.syspaths
Пример #9
0
def _run_command(args):
    cmd_str = ' '.join(quote(x) for x in args)
    log("running: %s" % cmd_str)

    p = popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout, stderr = p.communicate()
    return stdout, stderr, p.returncode
Пример #10
0
def exec_python(attr, src, executable="python"):
    """Runs a python subproc to calculate a package attribute.

    Args:
        attr (str): Name of package attribute being created.
        src (list of str): Python code to execute, will be converted into
            semicolon-delimited single line of code.

    Returns:
        str: Output of python process.
    """
    import subprocess

    if isinstance(src, basestring):
        src = [src]

    p = popen([executable, "-c", "; ".join(src)],
              stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out, err = p.communicate()

    if p.returncode:
        from rez.exceptions import InvalidPackageError
        raise InvalidPackageError(
            "Error determining package attribute '%s':\n%s" % (attr, err))

    return out.strip()
Пример #11
0
Файл: sh.py Проект: mottosso/rez
    def get_syspaths(cls):
        if cls.syspaths is not None:
            return cls.syspaths

        if config.standard_system_paths:
            cls.syspaths = config.standard_system_paths
            return cls.syspaths

        # detect system paths using registry
        cmd = "cmd=`which %s`; unset PATH; $cmd %s %s 'echo __PATHS_ $PATH'" \
              % (cls.name(), cls.norc_arg, cls.command_arg)
        p = popen(cmd, stdout=subprocess.PIPE,
                  stderr=subprocess.PIPE, shell=True)
        out_, err_ = p.communicate()
        if p.returncode:
            paths = []
        else:
            lines = out_.split('\n')
            line = [x for x in lines if "__PATHS_" in x.split()][0]
            paths = line.strip().split()[-1].split(os.pathsep)

        for path in os.defpath.split(os.path.pathsep):
            if path not in paths:
                paths.append(path)
        cls.syspaths = [x for x in paths if x]

        # add Rez binaries
        exe = which("rez-env")
        assert exe, "Could not find rez binary, this is a bug"
        rez_bin_dir = os.path.dirname(exe)
        cls.syspaths.insert(0, rez_bin_dir)

        return cls.syspaths
Пример #12
0
def find_site_python(module_name, paths=None):
    """Find the rez native python package that contains the given module.

    This function is used by python 'native' rez installers to find the native
    rez python package that represents the python installation that this module
    is installed into.

    Note:
        This function is dependent on the behavior found in the python '_native'
        package found in the 'rez-recipes' repository. Specifically, it expects
        to find a python package with a '_site_paths' list attribute listing
        the site directories associated with the python installation.

    Args:
        module_name (str): Target python module.
        paths (list of str, optional): paths to search for packages,
            defaults to `config.packages_path`.

    Returns:
        `Package`: Native python package containing the named module.
    """
    from rez.packages_ import iter_packages
    import subprocess
    import ast
    import os

    py_cmd = 'import {x}; print({x}.__path__)'.format(x=module_name)

    p = popen(["python", "-c", py_cmd],
              stdout=subprocess.PIPE,
              stderr=subprocess.PIPE)
    out, err = p.communicate()

    if p.returncode:
        raise InvalidPackageError(
            "Failed to find installed python module '%s':\n%s" %
            (module_name, err))

    module_paths = ast.literal_eval(out.strip())

    def issubdir(path, parent_path):
        return path.startswith(parent_path + os.sep)

    for package in iter_packages("python", paths=paths):
        if not hasattr(package, "_site_paths"):
            continue

        contained = True

        for module_path in module_paths:
            if not any(issubdir(module_path, x) for x in package._site_paths):
                contained = False

        if contained:
            return package

    raise InvalidPackageError(
        "Failed to find python installation containing the module '%s'. Has "
        "python been installed as a rez package?" % module_name)
Пример #13
0
def find_site_python(module_name, paths=None):
    """Find the rez native python package that contains the given module.

    This function is used by python 'native' rez installers to find the native
    rez python package that represents the python installation that this module
    is installed into.

    Note:
        This function is dependent on the behavior found in the python '_native'
        package found in the 'rez-recipes' repository. Specifically, it expects
        to find a python package with a '_site_paths' list attribute listing
        the site directories associated with the python installation.

    Args:
        module_name (str): Target python module.
        paths (list of str, optional): paths to search for packages,
            defaults to `config.packages_path`.

    Returns:
        `Package`: Native python package containing the named module.
    """
    from rez.packages_ import iter_packages
    import subprocess
    import ast
    import os

    py_cmd = 'import {x}; print {x}.__path__'.format(x=module_name)

    p = popen(["python", "-c", py_cmd], stdout=subprocess.PIPE,
               stderr=subprocess.PIPE)
    out, err = p.communicate()

    if p.returncode:
        raise InvalidPackageError(
            "Failed to find installed python module '%s':\n%s"
            % (module_name, err))

    module_paths = ast.literal_eval(out.strip())

    def issubdir(path, parent_path):
        return path.startswith(parent_path + os.sep)

    for package in iter_packages("python", paths=paths):
        if not hasattr(package, "_site_paths"):
            continue

        contained = True

        for module_path in module_paths:
            if not any(issubdir(module_path, x) for x in package._site_paths):
                contained = False

        if contained:
            return package

    raise InvalidPackageError(
        "Failed to find python installation containing the module '%s'. Has "
        "python been installed as a rez package?" % module_name)
Пример #14
0
    def subprocess(self, args, **subproc_kwargs):
        if self.manager:
            self.target_environ.update(self.manager.environ)

        shell_mode = not hasattr(args, '__iter__')
        return popen(args,
                     shell=shell_mode,
                     env=self.target_environ,
                     **subproc_kwargs)
Пример #15
0
    def subprocess(self, args, **subproc_kwargs):
        if self.manager:
            self.target_environ.update(self.manager.environ)

        shell_mode = isinstance(args, basestring)
        return popen(args,
                     shell=shell_mode,
                     env=self.target_environ,
                     **subproc_kwargs)
Пример #16
0
    def subprocess(self, args, **subproc_kwargs):
        if self.manager:
            self.target_environ.update(self.manager.environ)

        shell_mode = not hasattr(args, '__iter__')
        return popen(args,
                     shell=shell_mode,
                     env=self.target_environ,
                     **subproc_kwargs)
Пример #17
0
 def open(self, section_index=0):
     """Launch a help section."""
     uri = self._sections[section_index][1]
     if len(uri.split()) == 1:
         self._open_url(uri)
     else:
         if self._verbose:
             print "running command: %s" % uri
         p = popen(uri, shell=True)
         p.wait()
Пример #18
0
 def open(self, section_index=0):
     """Launch a help section."""
     uri = self._sections[section_index][1]
     if len(uri.split()) == 1:
         self._open_url(uri)
     else:
         if self._verbose:
             print "running command: %s" % uri
         p = popen(uri, shell=True)
         p.wait()
Пример #19
0
 def _open_url(cls, url):
     if config.browser:
         cmd = [config.browser, url]
         if not config.quiet:
             print "running command: %s" % " ".join(cmd)
         p = popen(cmd)
         p.communicate()
     else:
         if not config.quiet:
             print "opening URL in browser: %s" % url
         webbrowser.open_new(url)
Пример #20
0
 def _open_url(cls, url):
     if config.browser:
         cmd = [config.browser, url]
         if not config.quiet:
             print "running command: %s" % " ".join(cmd)
         p = popen(cmd)
         p.communicate()
     else:
         if not config.quiet:
             print "opening URL in browser: %s" % url
         webbrowser.open_new(url)
Пример #21
0
    def _physical_cores_from_osx_sysctl(self):
        import subprocess
        try:
            p = popen(['sysctl', '-n', 'hw.physicalcpu'],
                      stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        except (OSError, IOError):
            return None

        stdout, stderr = p.communicate()
        if p.returncode:
            return None

        return int(stdout.strip())
Пример #22
0
def _cmd(context, command):
    cmd_str = ' '.join(quote(x) for x in command)
    _log("running: %s" % cmd_str)

    if context is None:
        p = popen(command)
    else:
        p = context.execute_shell(command=command, block=False)

    p.wait()

    if p.returncode:
        raise BuildError("Failed to download source with pip: %s" % cmd_str)
Пример #23
0
    def _physical_cores_from_osx_sysctl(self):
        import subprocess
        try:
            p = popen(['sysctl', '-n', 'hw.physicalcpu'],
                      stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        except (OSError, IOError):
            return None

        stdout, stderr = p.communicate()
        if p.returncode:
            return None

        return int(stdout.strip())
Пример #24
0
def _cmd(context, command):
    cmd_str = ' '.join(quote(x) for x in command)
    _log("running: %s" % cmd_str)

    if context is None:
        p = popen(command)
    else:
        p = context.execute_shell(command=command, block=False)

    p.wait()

    if p.returncode:
        raise BuildError("Failed to download source with pip: %s" % cmd_str)
Пример #25
0
def exec_command(attr, cmd):
    """Runs a subproc to calculate a package attribute.
    """
    import subprocess

    p = popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out, err = p.communicate()

    if p.returncode:
        from rez.exceptions import InvalidPackageError
        raise InvalidPackageError(
            "Error determining package attribute '%s':\n%s" % (attr, err))

    return out.strip(), err.strip()
Пример #26
0
def exec_command(attr, cmd):
    """Runs a subproc to calculate a package attribute.
    """
    import subprocess

    p = popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    out, err = p.communicate()

    if p.returncode:
        from rez.exceptions import InvalidPackageError
        raise InvalidPackageError(
            "Error determining package attribute '%s':\n%s" % (attr, err))

    return out.strip(), err.strip()
Пример #27
0
def run_pip_command(command_args, pip_version=None, python_version=None):
    """Run a pip command.
    Args:
        command_args (list of str): Args to pip.
    Returns:
        `subprocess.Popen`: Pip process.
    """
    pip_exe, context = find_pip(pip_version, python_version)
    command = [pip_exe] + list(command_args)

    if context is None:
        return popen(command)
    else:
        return context.execute_shell(command=command, block=False)
Пример #28
0
def _run_command(args):
    cmd_str = ' '.join(quote(x) for x in args)
    log("running: %s" % cmd_str)

    # https://github.com/nerdvegas/rez/pull/659
    use_shell = ("Windows" in platform.system())

    p = popen(args,
              stdout=subprocess.PIPE,
              stderr=subprocess.PIPE,
              shell=use_shell,
              universal_newlines=True)

    stdout, stderr = p.communicate()
    return stdout, stderr, p.returncode
Пример #29
0
def run_pip_command(command_args, python_version=None):
    """Run a pip command.

    Args:
        command_args (list of str): Args to pip.

    Returns:
        `subprocess.Popen`: Pip process.
    """
    python_exe, context = find_python(python_version)
    command = [python_exe, "-m", "pip"] + list(command_args)

    if context is None:
        return popen(command)
    else:
        return context.execute_shell(command=command, block=False)
Пример #30
0
    def _cmd(self, *nargs):
        """Convenience function for executing a program such as 'git' etc."""
        cmd_str = ' '.join(map(quote, nargs))

        if self.package.config.debug("package_release"):
            print_debug("Running command: %s" % cmd_str)

        p = popen(nargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                  cwd=self.pkg_root)
        out, err = p.communicate()

        if p.returncode:
            print_debug("command stdout:")
            print_debug(out)
            print_debug("command stderr:")
            print_debug(err)
            raise ReleaseVCSError("command failed: %s\n%s" % (cmd_str, err))
        out = out.strip()
        if out:
            return [x.rstrip() for x in out.split('\n')]
        else:
            return []
Пример #31
0
    def _cmd(self, *nargs):
        """Convenience function for executing a program such as 'git' etc."""
        cmd_str = ' '.join(map(quote, nargs))

        if self.package.config.debug("package_release"):
            print_debug("Running command: %s" % cmd_str)

        p = popen(nargs,
                  stdout=subprocess.PIPE,
                  stderr=subprocess.PIPE,
                  cwd=self.pkg_root)
        out, err = p.communicate()

        if p.returncode:
            print_debug("command stdout:")
            print_debug(out)
            print_debug("command stderr:")
            print_debug(err)
            raise ReleaseVCSError("command failed: %s\n%s" % (cmd_str, err))
        out = out.strip()
        if out:
            return [x.rstrip() for x in out.split('\n')]
        else:
            return []
Пример #32
0
def view_graph(graph_str, dest_file=None):
    """View a dot graph in an image viewer."""
    from rez.system import system
    from rez.config import config

    if (system.platform == "linux") and (not os.getenv("DISPLAY")):
        print >> sys.stderr, "Unable to open display."
        sys.exit(1)

    dest_file = _write_graph(graph_str, dest_file=dest_file)

    # view graph
    viewed = False
    prog = config.image_viewer or 'browser'
    print "loading image viewer (%s)..." % prog

    if config.image_viewer:
        proc = popen([config.image_viewer, dest_file])
        proc.wait()
        viewed = not bool(proc.returncode)

    if not viewed:
        import webbrowser
        webbrowser.open_new("file://" + dest_file)
Пример #33
0
def view_graph(graph_str, dest_file=None):
    """View a dot graph in an image viewer."""
    from rez.system import system
    from rez.config import config

    if (system.platform == "linux") and (not os.getenv("DISPLAY")):
        print("Unable to open display.", file=sys.stderr)
        sys.exit(1)

    dest_file = _write_graph(graph_str, dest_file=dest_file)

    # view graph
    viewed = False
    prog = config.image_viewer or 'browser'
    print("loading image viewer (%s)..." % prog)

    if config.image_viewer:
        proc = popen([config.image_viewer, dest_file])
        proc.wait()
        viewed = not bool(proc.returncode)

    if not viewed:
        import webbrowser
        webbrowser.open_new("file://" + dest_file)
Пример #34
0
    def get_syspaths(cls):
        if cls.syspaths is not None:
            return cls.syspaths

        if config.standard_system_paths:
            cls.syspaths = config.standard_system_paths
            return cls.syspaths

        # detect system paths using registry
        def gen_expected_regex(parts):
            whitespace = r"[\s]+"
            return whitespace.join(parts)

        # TODO: Research if there is an easier way to pull system PATH from
        # registry in powershell
        paths = []

        cmd = [
            "REG", "QUERY",
            ("HKLM\\SYSTEM\\CurrentControlSet\\"
             "Control\\Session Manager\\Environment"), "/v", "PATH"
        ]

        expected = gen_expected_regex([
            ("HKEY_LOCAL_MACHINE\\\\SYSTEM\\\\CurrentControlSet\\\\"
             "Control\\\\Session Manager\\\\Environment"), "PATH",
            "REG_(EXPAND_)?SZ", "(.*)"
        ])

        p = popen(cmd,
                  stdout=PIPE,
                  stderr=PIPE,
                  universal_newlines=True,
                  shell=True)
        out_, _ = p.communicate()
        out_ = out_.strip()

        if p.returncode == 0:
            match = re.match(expected, out_)
            if match:
                paths.extend(match.group(2).split(os.pathsep))

        cmd = ["REG", "QUERY", "HKCU\\Environment", "/v", "PATH"]

        expected = gen_expected_regex([
            "HKEY_CURRENT_USER\\\\Environment", "PATH", "REG_(EXPAND_)?SZ",
            "(.*)"
        ])

        p = popen(cmd,
                  stdout=PIPE,
                  stderr=PIPE,
                  universal_newlines=True,
                  shell=True)
        out_, _ = p.communicate()
        out_ = out_.strip()

        if p.returncode == 0:
            match = re.match(expected, out_)
            if match:
                paths.extend(match.group(2).split(os.pathsep))

        cls.syspaths = list(set([x for x in paths if x]))

        # add Rez binaries
        exe = which("rez-env")
        assert exe, "Could not find rez binary, this is a bug"
        rez_bin_dir = os.path.dirname(exe)
        cls.syspaths.insert(0, rez_bin_dir)

        return cls.syspaths
Пример #35
0
    def spawn_shell(self,
                    context_file,
                    tmpdir,
                    rcfile=None,
                    norc=False,
                    stdin=False,
                    command=None,
                    env=None,
                    quiet=False,
                    pre_command=None,
                    **Popen_args):

        startup_sequence = self.get_startup_sequence(rcfile, norc, bool(stdin),
                                                     command)
        shell_command = None

        def _record_shell(ex, files, bind_rez=True, print_msg=False):
            ex.source(context_file)
            if startup_sequence["envvar"]:
                ex.unsetenv(startup_sequence["envvar"])
            if bind_rez:
                ex.interpreter._bind_interactive_rez()
            if print_msg and not quiet:
                if system.is_production_rez_install:
                    # previously this was called with the /K flag, however
                    # that would leave spawn_shell hung on a blocked call
                    # waiting for the user to type "exit" into the shell that
                    # was spawned to run the rez context printout
                    ex.command("cmd /Q /C rez context")

        def _create_ex():
            return RexExecutor(interpreter=self.new_shell(),
                               parent_environ={},
                               add_default_namespaces=False)

        executor = _create_ex()

        if self.settings.prompt:
            newprompt = '%%REZ_ENV_PROMPT%%%s' % self.settings.prompt
            executor.interpreter._saferefenv('REZ_ENV_PROMPT')
            executor.env.REZ_ENV_PROMPT = literal(newprompt)

        if startup_sequence["command"] is not None:
            _record_shell(executor, files=startup_sequence["files"])
            shell_command = startup_sequence["command"]
        else:
            _record_shell(executor,
                          files=startup_sequence["files"],
                          print_msg=(not quiet))

        if shell_command:
            # Launch the provided command in the configured shell and wait
            # until it exits.
            executor.command(shell_command)

        # Test for None specifically because resolved_context.execute_rex_code
        # passes '' and we do NOT want to keep a shell open during a rex code
        # exec operation.
        elif shell_command is None:
            # Launch the configured shell itself and wait for user interaction
            # to exit.
            executor.command('cmd /Q /K')

        # Exit the configured shell.
        executor.command('exit %errorlevel%')

        code = executor.get_output()
        target_file = os.path.join(tmpdir,
                                   "rez-shell.%s" % self.file_extension())

        with open(target_file, 'w') as f:
            f.write(code)

        if startup_sequence["stdin"] and stdin and (stdin is not True):
            Popen_args["stdin"] = stdin

        cmd = []
        if pre_command:
            if isinstance(pre_command, basestring):
                cmd = pre_command.strip().split()
            else:
                cmd = pre_command

        if shell_command:
            cmd_flags = ['/Q', '/C']
        else:
            cmd_flags = ['/Q', '/K']

        cmd = cmd + [self.executable
                     ] + cmd_flags + ['call {}'.format(target_file)]
        is_detached = (cmd[0] == 'START')

        p = popen(cmd, env=env, shell=is_detached, **Popen_args)
        return p
Пример #36
0
    def spawn_shell(self, context_file, tmpdir, rcfile=None, norc=False,
                    stdin=False, command=None, env=None, quiet=False,
                    pre_command=None, **Popen_args):

        startup_sequence = self.get_startup_sequence(rcfile, norc, bool(stdin), command)
        shell_command = None

        def _record_shell(ex, files, bind_rez=True, print_msg=False):
            ex.source(context_file)
            if startup_sequence["envvar"]:
                ex.unsetenv(startup_sequence["envvar"])
            if bind_rez:
                ex.interpreter._bind_interactive_rez()
            if print_msg and not quiet:
                if system.is_production_rez_install:
                    # previously this was called with the /K flag, however
                    # that would leave spawn_shell hung on a blocked call
                    # waiting for the user to type "exit" into the shell that
                    # was spawned to run the rez context printout
                    ex.command("cmd /Q /C rez context")

        def _create_ex():
            return RexExecutor(interpreter=self.new_shell(),
                               parent_environ={},
                               add_default_namespaces=False)

        executor = _create_ex()

        if self.settings.prompt:
            newprompt = '%%REZ_ENV_PROMPT%%%s' % self.settings.prompt
            executor.interpreter._saferefenv('REZ_ENV_PROMPT')
            executor.env.REZ_ENV_PROMPT = literal(newprompt)

        if startup_sequence["command"] is not None:
            _record_shell(executor, files=startup_sequence["files"])
            shell_command = startup_sequence["command"]
        else:
            _record_shell(executor, files=startup_sequence["files"], print_msg=(not quiet))

        if shell_command:
            # Launch the provided command in the configured shell and wait
            # until it exits.
            executor.command(shell_command)

        # Test for None specifically because resolved_context.execute_rex_code
        # passes '' and we do NOT want to keep a shell open during a rex code
        # exec operation.
        elif shell_command is None: 
            # Launch the configured shell itself and wait for user interaction
            # to exit.
            executor.command('cmd /Q /K')
            
        # Exit the configured shell.
        executor.command('exit %errorlevel%')

        code = executor.get_output()
        target_file = os.path.join(tmpdir, "rez-shell.%s"
                                   % self.file_extension())

        with open(target_file, 'w') as f:
            f.write(code)

        if startup_sequence["stdin"] and stdin and (stdin is not True):
            Popen_args["stdin"] = stdin

        cmd = []
        if pre_command:
            if isinstance(pre_command, basestring):
                cmd = pre_command.strip().split()
            else:
                cmd = pre_command

        if shell_command:
            cmd_flags = ['/Q', '/C']
        else:
            cmd_flags = ['/Q', '/K']

        cmd = cmd + [self.executable] + cmd_flags + ['call {}'.format(target_file)]
        is_detached = (cmd[0] == 'START')

        p = popen(cmd, env=env, shell=is_detached, **Popen_args)
        return p
Пример #37
0
    def _os(self):
        distributor = None
        release = None

        def _str(s):
            if (s.startswith("'") and s.endswith("'")) \
                    or (s.startswith('"') and s.endswith('"')):
                return s[1:-1]
            else:
                return s

        def _os():
            if distributor and release:
                return "%s-%s" % (distributor, release)
            else:
                return None

        def _parse(txt, distributor_key, release_key):
            distributor_ = None
            release_ = None
            lines = txt.strip().split('\n')
            for line in lines:
                if line.startswith(distributor_key):
                    s = line[len(distributor_key):].strip()
                    distributor_ = _str(s)
                elif line.startswith(release_key):
                    s = line[len(release_key):].strip()
                    release_ = _str(s)
            return distributor_, release_

        # first try parsing the /etc/lsb-release file
        file = "/etc/lsb-release"
        if os.path.isfile(file):
            with open(file) as f:
                txt = f.read()
            distributor, release = _parse(txt,
                                          "DISTRIB_ID=",
                                          "DISTRIB_RELEASE=")
            result = _os()
            if result:
                return result

        # next, try getting the output of the lsb_release program
        import subprocess

        p = popen(['/usr/bin/env', 'lsb_release', '-a'],
                  stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        txt = p.communicate()[0]

        if not p.returncode:
            distributor_, release_ = _parse(txt,
                                            "Distributor ID:",
                                            "Release:")
            if distributor_ and not distributor:
                distributor = distributor_
            if release_ and not release:
                release = release_

            result = _os()
            if result:
                return result

        # try to read the /etc/os-release file
        # this file contains OS specific data on linux
        # distributions
        # see https://www.freedesktop.org/software/systemd/man/os-release.html
        os_release = '/etc/os-release'
        if os.path.isfile(os_release):
            with open(os_release, 'r') as f:
                txt = f.read()
            distributor_, release_ = _parse(txt,
                                            "ID=",
                                            "VERSION_ID=")
            if distributor_ and not distributor:
                distributor = distributor_
            if release_ and not release:
                release = release_

            result = _os()
            if result:
                return result

        # last, use python's dist detection. It is known to return incorrect
        # info on some systems though
        try:
            distributor_, release_, _ = platform.linux_distribution()
        except:
            distributor_, release_, _ = platform.dist()

        if distributor_ and not distributor:
            distributor = distributor_
        if release_ and not release:
            release = release_

        result = _os()
        if result:
            return result

        # last resort, accept missing release
        if distributor:
            return distributor

        # give up
        raise RezSystemError("cannot detect operating system")
Пример #38
0
    def get_syspaths(cls):
        if cls.syspaths is not None:
            return cls.syspaths

        if config.standard_system_paths:
            cls.syspaths = config.standard_system_paths
            return cls.syspaths

        # detect system paths using registry
        def gen_expected_regex(parts):
            whitespace = "[\s]+"
            return whitespace.join(parts)

        paths = []

        cmd = [
            "REG",
            "QUERY",
            "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment",
            "/v",
            "PATH"
        ]

        expected = gen_expected_regex([
            "HKEY_LOCAL_MACHINE\\\\SYSTEM\\\\CurrentControlSet\\\\Control\\\\Session Manager\\\\Environment",
            "PATH",
            "REG_(EXPAND_)?SZ",
            "(.*)"
        ])

        p = popen(cmd, stdout=subprocess.PIPE,
                  stderr=subprocess.PIPE, shell=True)
        out_, _ = p.communicate()
        out_ = out_.strip()

        if p.returncode == 0:
            match = re.match(expected, out_)
            if match:
                paths.extend(match.group(2).split(os.pathsep))

        cmd = [
            "REG",
            "QUERY",
            "HKCU\\Environment",
            "/v",
            "PATH"
        ]

        expected = gen_expected_regex([
            "HKEY_CURRENT_USER\\\\Environment",
            "PATH",
            "REG_(EXPAND_)?SZ",
            "(.*)"
        ])

        p = popen(cmd, stdout=subprocess.PIPE,
                  stderr=subprocess.PIPE, shell=True)
        out_, _ = p.communicate()
        out_ = out_.strip()

        if p.returncode == 0:
            match = re.match(expected, out_)
            if match:
                paths.extend(match.group(2).split(os.pathsep))

        cls.syspaths = set([x for x in paths if x])
        return cls.syspaths
Пример #39
0
    def spawn_shell(self,
                    context_file,
                    tmpdir,
                    rcfile=None,
                    norc=False,
                    stdin=False,
                    command=None,
                    env=None,
                    quiet=False,
                    pre_command=None,
                    **Popen_args):

        startup_sequence = self.get_startup_sequence(rcfile, norc, bool(stdin),
                                                     command)
        shell_command = None

        def _record_shell(ex, files, bind_rez=True, print_msg=False):
            ex.source(context_file)
            if startup_sequence["envvar"]:
                ex.unsetenv(startup_sequence["envvar"])
            if bind_rez:
                ex.interpreter._bind_interactive_rez()
            if print_msg and not quiet:
                # Rez may not be available
                ex.command("Try { rez context } Catch { }")

        executor = RexExecutor(interpreter=self.new_shell(),
                               parent_environ={},
                               add_default_namespaces=False)

        if startup_sequence["command"] is not None:
            _record_shell(executor, files=startup_sequence["files"])
            shell_command = startup_sequence["command"]
        else:
            _record_shell(executor,
                          files=startup_sequence["files"],
                          print_msg=(not quiet))

        self._additional_commands(executor)

        if shell_command:
            executor.command(shell_command)

        # Forward exit call to parent PowerShell process
        executor.command("exit $LastExitCode")

        code = executor.get_output()
        target_file = os.path.join(tmpdir,
                                   "rez-shell.%s" % self.file_extension())

        with open(target_file, 'w') as f:
            f.write(code)

        cmd = []
        if pre_command:
            cmd = pre_command

            if not isinstance(cmd, (tuple, list)):
                cmd = pre_command.rstrip().split()

        cmd += [self.executable]

        # Suppresses copyright message of PowerShell and pwsh
        cmd += ["-NoLogo"]

        # Generic form of sourcing that works in powershell and pwsh
        cmd += ["-File", target_file]

        if shell_command is None:
            cmd.insert(1, "-NoExit")

        p = popen(cmd, env=env, **Popen_args)
        return p
Пример #40
0
Файл: cmd.py Проект: opcg/rez
    def spawn_shell(self,
                    context_file,
                    tmpdir,
                    rcfile=None,
                    norc=False,
                    stdin=False,
                    command=None,
                    env=None,
                    quiet=False,
                    pre_command=None,
                    **Popen_args):

        startup_sequence = self.get_startup_sequence(rcfile, norc, bool(stdin),
                                                     command)
        shell_command = None

        def _record_shell(ex, files, bind_rez=True, print_msg=False):
            ex.source(context_file)
            if startup_sequence["envvar"]:
                ex.unsetenv(startup_sequence["envvar"])
            if bind_rez:
                ex.interpreter._bind_interactive_rez()
            if print_msg and not quiet:
                ex.info('You are now in a rez-configured environment.')

                # Output, if Rez is present
                ex.command("rez context 2>nul")

        def _create_ex():
            return RexExecutor(interpreter=self.new_shell(),
                               parent_environ={},
                               add_default_namespaces=False)

        executor = _create_ex()

        if self.settings.prompt:
            newprompt = '%%REZ_ENV_PROMPT%%%s' % self.settings.prompt
            executor.interpreter._saferefenv('REZ_ENV_PROMPT')
            executor.env.REZ_ENV_PROMPT = literal(newprompt)

        if startup_sequence["command"] is not None:
            _record_shell(executor, files=startup_sequence["files"])
            shell_command = startup_sequence["command"]
        else:
            _record_shell(executor,
                          files=startup_sequence["files"],
                          print_msg=(not quiet))

        code = executor.get_output()
        target_file = os.path.join(tmpdir,
                                   "rez-shell.%s" % self.file_extension())

        with open(target_file, 'w') as f:
            f.write(code)

        if startup_sequence["stdin"] and stdin and (stdin is not True):
            Popen_args["stdin"] = stdin

        cmd = []
        if pre_command:
            if isinstance(pre_command, basestring):
                cmd = pre_command.strip().split()
            else:
                cmd = pre_command

        # Test for None specifically because resolved_context.execute_rex_code
        # passes '' and we do NOT want to keep a shell open during a rex code
        # exec operation.
        if shell_command is None:
            cmd_flags = ['/Q', '/K']
        else:
            cmd_flags = ['/Q', '/C']

        cmd += [self.executable]
        cmd += cmd_flags
        cmd += ['call {}'.format(target_file)]

        if shell_command:
            cmd += ["& " + shell_command]

        is_detached = (cmd[0] == 'START')

        # No environment was explicity passed
        if not env and not config.inherit_parent_environment:
            env = self.environment()

        p = popen(cmd,
                  env=env,
                  shell=is_detached,
                  universal_newlines=True,
                  **Popen_args)
        return p
Пример #41
0
Файл: shells.py Проект: opcg/rez
    def spawn_shell(self,
                    context_file,
                    tmpdir,
                    rcfile=None,
                    norc=False,
                    stdin=False,
                    command=None,
                    env=None,
                    quiet=False,
                    pre_command=None,
                    add_rez=True,
                    package_commands_sourced_first=None,
                    **Popen_args):

        d = self.get_startup_sequence(rcfile, norc, bool(stdin), command)
        envvar = d["envvar"]
        files = d["files"]
        bind_files = d["bind_files"]
        do_rcfile = d["do_rcfile"]
        shell_command = None

        if package_commands_sourced_first is None:
            package_commands_sourced_first = config.package_commands_sourced_first

        def _record_shell(ex, files, bind_rez=True, print_msg=False):
            if bind_rez and package_commands_sourced_first:
                ex.source(context_file)

            for file_ in files:
                if os.path.exists(os.path.expanduser(file_)):
                    ex.source(file_)

            if bind_rez and not package_commands_sourced_first:
                ex.source(context_file)

            if envvar:
                ex.unsetenv(envvar)
            if add_rez and bind_rez:
                ex.interpreter._bind_interactive_rez()
            if print_msg and add_rez and not quiet:
                ex.info('')
                ex.info('You are now in a rez-configured environment.')
                ex.info('')
                ex.command(
                    # Call rez, if it's there
                    'command -v rezolve >/dev/null 2>&1 '
                    '&& rezolve context')

        def _write_shell(ex, filename):
            code = ex.get_output()
            target_file = os.path.join(tmpdir, filename)
            with open(target_file, 'w') as f:
                f.write(code)
            return target_file

        def _create_ex():
            return RexExecutor(interpreter=self.new_shell(),
                               parent_environ={},
                               add_default_namespaces=False)

        executor = _create_ex()

        if self.settings.prompt:
            newprompt = '${REZ_ENV_PROMPT}%s' % self.settings.prompt
            executor.interpreter._saferefenv('REZ_ENV_PROMPT')
            executor.env.REZ_ENV_PROMPT = newprompt

        if d["command"] is not None:
            _record_shell(executor, files=files)
            shell_command = d["command"]
        else:
            if d["stdin"]:
                assert (self.stdin_arg)
                shell_command = "%s %s" % (self.executable, self.stdin_arg)
                quiet = True
            elif do_rcfile:
                assert (self.rcfile_arg)
                shell_command = "%s %s" % (self.executable, self.rcfile_arg)
            else:
                shell_command = self.executable

            if do_rcfile:
                # hijack rcfile to insert our own script
                ex = _create_ex()
                _record_shell(ex, files=files, print_msg=(not quiet))
                filename = "rcfile.%s" % self.file_extension()
                filepath = _write_shell(ex, filename)
                shell_command += " %s" % filepath
            elif envvar:
                # hijack env-var to insert our own script
                ex = _create_ex()
                _record_shell(ex, files=files, print_msg=(not quiet))
                filename = "%s.%s" % (envvar, self.file_extension())
                filepath = _write_shell(ex, filename)
                executor.setenv(envvar, filepath)
            else:
                # hijack $HOME to insert our own script
                files = [x for x in files if x not in bind_files
                         ] + list(bind_files)

                if files:
                    for file_ in files:
                        if file_ in bind_files:
                            bind_rez = True
                            files_ = [file_] if d["source_bind_files"] else []
                        else:
                            bind_rez = False
                            files_ = [file_]

                        ex = _create_ex()
                        ex.setenv('HOME', os.environ.get('HOME', ''))
                        _record_shell(ex,
                                      files=files_,
                                      bind_rez=bind_rez,
                                      print_msg=bind_rez)
                        _write_shell(ex, os.path.basename(file_))

                    executor.setenv("HOME", tmpdir)

                    # keep history
                    if self.histfile and self.histvar:
                        histfile = os.path.expanduser(self.histfile)
                        if os.path.exists(histfile):
                            executor.setenv(self.histvar, histfile)
                else:
                    if config.warn("shell_startup"):
                        print_warning(
                            "WARNING: Could not configure environment from "
                            "within the target shell (%s); this has been done "
                            "in the parent process instead." % self.name())
                    executor.source(context_file)

        if shell_command:  # an empty string means 'run no command and exit'
            executor.command(shell_command)
        executor.command("exit %s" % self.last_command_status)

        code = executor.get_output()
        target_file = os.path.join(tmpdir,
                                   "rez-shell.%s" % self.file_extension())
        with open(target_file, 'w') as f:
            f.write(code)

        if d["stdin"] and stdin and (stdin is not True):
            Popen_args["stdin"] = stdin

        cmd = []
        if pre_command:
            if isinstance(pre_command, six.string_types):
                cmd = pre_command.strip().split()
            else:
                cmd = pre_command
        cmd.extend([self.executable, target_file])

        # No environment was explicity passed
        if not env and not config.inherit_parent_environment:
            env = self.environment()

        try:
            p = popen(
                cmd,
                env=env,
                universal_newlines=True,  # text-mode
                **Popen_args)
        except Exception as e:
            cmd_str = ' '.join(map(pipes.quote, cmd))
            raise RezSystemError("Error running command:\n%s\n%s" %
                                 (cmd_str, str(e)))
        return p
Пример #42
0
    def _os(self):
        distributor = None
        release = None

        def _str(s):
            if (s.startswith("'") and s.endswith("'")) \
                    or (s.startswith('"') and s.endswith('"')):
                return s[1:-1]
            else:
                return s

        def _os():
            if distributor and release:
                return "%s-%s" % (distributor, release)
            else:
                return None

        def _parse(txt, distributor_key, release_key):
            distributor_ = None
            release_ = None
            lines = txt.strip().split('\n')
            for line in lines:
                if line.startswith(distributor_key):
                    s = line[len(distributor_key):].strip()
                    distributor_ = _str(s)
                elif line.startswith(release_key):
                    s = line[len(release_key):].strip()
                    release_ = _str(s)
            return distributor_, release_

        # first try parsing the /etc/lsb-release file
        file = "/etc/lsb-release"
        if os.path.isfile(file):
            with open(file) as f:
                txt = f.read()
            distributor, release = _parse(txt, "DISTRIB_ID=",
                                          "DISTRIB_RELEASE=")
        result = _os()
        if result:
            return result

        # next, try getting the output of the lsb_release program
        import subprocess

        p = popen(['/usr/bin/env', 'lsb_release', '-a'],
                  stdout=subprocess.PIPE,
                  stderr=subprocess.PIPE)
        txt = p.communicate()[0]

        if not p.returncode:
            distributor_, release_ = _parse(txt, "Distributor ID:", "Release:")
            if distributor_ and not distributor:
                distributor = distributor_
            if release_ and not release:
                release = release_

        result = _os()
        if result:
            return result

        # last, use python's dist detection. It is known to return incorrect
        # info on some systems though
        try:
            distributor_, release_, _ = platform.linux_distribution()
        except:
            distributor_, release_, _ = platform.dist()

        if distributor_ and not distributor:
            distributor = distributor_
        if release_ and not release:
            release = release_
        result = _os()
        if result:
            return result

        # last resort, accept missing release
        if distributor:
            return distributor

        # give up
        raise RezSystemError("cannot detect operating system")
Пример #43
0
    def spawn_shell(self,
                    context_file,
                    tmpdir,
                    rcfile=None,
                    norc=False,
                    stdin=False,
                    command=None,
                    env=None,
                    quiet=False,
                    pre_command=None,
                    **Popen_args):

        startup_sequence = self.get_startup_sequence(rcfile, norc, bool(stdin),
                                                     command)
        shell_command = None

        def _record_shell(ex, files, bind_rez=True, print_msg=False):
            ex.source(context_file)
            if startup_sequence["envvar"]:
                ex.unsetenv(startup_sequence["envvar"])
            if bind_rez:
                ex.interpreter._bind_interactive_rez()
            if print_msg and not quiet:
                ex.info('You are now in a rez-configured environment.')

                # Rez may not be available.
                # Or it may not have an associated Python interpreter
                # available, in which case the command will succeed
                # but output to stderr, muted with 2>$null
                ex.command("Try { rez context 2>$null } Catch { }")

        executor = RexExecutor(interpreter=self.new_shell(),
                               parent_environ={},
                               add_default_namespaces=False)

        if startup_sequence["command"] is not None:
            _record_shell(executor, files=startup_sequence["files"])
            shell_command = startup_sequence["command"]
        else:
            _record_shell(executor,
                          files=startup_sequence["files"],
                          print_msg=(not quiet))

        if shell_command:
            executor.command(shell_command)

        # Forward exit call to parent PowerShell process
        executor.command("exit $LastExitCode")

        code = executor.get_output()
        target_file = os.path.join(tmpdir,
                                   "rez-shell.%s" % self.file_extension())

        with open(target_file, 'w') as f:
            f.write(code)

        cmd = []
        if pre_command:
            cmd = pre_command

            if not isinstance(cmd, (tuple, list)):
                cmd = pre_command.rstrip().split()

        cmd += [
            self.executable,
            "-NoLogo ",

            # Prevent custom user profile from leaking into
            # the resulting environment.
            "-NoProfile ",

            # Establish a session within which arbitrary
            # PowerShell scripts may be run.
            "-ExecutionPolicy",
            "Unrestricted",

            # Start from this script
            '. "{}"'.format(target_file)
        ]

        if shell_command is None:
            cmd.insert(1, "-NoExit")

        # No environment was explicity passed
        if not env and not config.inherit_parent_environment:
            env = self.environment()

        p = popen(cmd, env=env, universal_newlines=True, **Popen_args)
        return p
Пример #44
0
    def spawn_shell(self, context_file, tmpdir, rcfile=None, norc=False,
                    stdin=False, command=None, env=None, quiet=False,
                    pre_command=None, add_rez=True,
                    package_commands_sourced_first=None, **Popen_args):

        d = self.get_startup_sequence(rcfile, norc, bool(stdin), command)
        envvar = d["envvar"]
        files = d["files"]
        bind_files = d["bind_files"]
        do_rcfile = d["do_rcfile"]
        shell_command = None

        if package_commands_sourced_first is None:
            package_commands_sourced_first = config.package_commands_sourced_first

        def _record_shell(ex, files, bind_rez=True, print_msg=False):
            if bind_rez and package_commands_sourced_first:
                ex.source(context_file)

            for file_ in files:
                if os.path.exists(os.path.expanduser(file_)):
                    ex.source(file_)

            if bind_rez and not package_commands_sourced_first:
                ex.source(context_file)

            if envvar:
                ex.unsetenv(envvar)
            if add_rez and bind_rez:
                ex.interpreter._bind_interactive_rez()
            if print_msg and add_rez and not quiet:
                ex.info('')
                ex.info('You are now in a rez-configured environment.')
                ex.info('')
                ex.command('rezolve context')

        def _write_shell(ex, filename):
            code = ex.get_output()
            target_file = os.path.join(tmpdir, filename)
            with open(target_file, 'w') as f:
                f.write(code)
            return target_file

        def _create_ex():
            return RexExecutor(interpreter=self.new_shell(),
                               parent_environ={},
                               add_default_namespaces=False)

        executor = _create_ex()

        if self.settings.prompt:
            newprompt = '${REZ_ENV_PROMPT}%s' % self.settings.prompt
            executor.interpreter._saferefenv('REZ_ENV_PROMPT')
            executor.env.REZ_ENV_PROMPT = newprompt

        if d["command"] is not None:
            _record_shell(executor, files=files)
            shell_command = d["command"]
        else:
            if d["stdin"]:
                assert(self.stdin_arg)
                shell_command = "%s %s" % (self.executable, self.stdin_arg)
                quiet = True
            elif do_rcfile:
                assert(self.rcfile_arg)
                shell_command = "%s %s" % (self.executable, self.rcfile_arg)
            else:
                shell_command = self.executable

            if do_rcfile:
                # hijack rcfile to insert our own script
                ex = _create_ex()
                _record_shell(ex, files=files, print_msg=(not quiet))
                filename = "rcfile.%s" % self.file_extension()
                filepath = _write_shell(ex, filename)
                shell_command += " %s" % filepath
            elif envvar:
                # hijack env-var to insert our own script
                ex = _create_ex()
                _record_shell(ex, files=files, print_msg=(not quiet))
                filename = "%s.%s" % (envvar, self.file_extension())
                filepath = _write_shell(ex, filename)
                executor.setenv(envvar, filepath)
            else:
                # hijack $HOME to insert our own script
                files = [x for x in files if x not in bind_files] + list(bind_files)

                if files:
                    for file_ in files:
                        if file_ in bind_files:
                            bind_rez = True
                            files_ = [file_] if d["source_bind_files"] else []
                        else:
                            bind_rez = False
                            files_ = [file_]

                        ex = _create_ex()
                        ex.setenv('HOME', os.environ.get('HOME', ''))
                        _record_shell(ex, files=files_, bind_rez=bind_rez,
                                      print_msg=bind_rez)
                        _write_shell(ex, os.path.basename(file_))

                    executor.setenv("HOME", tmpdir)

                    # keep history
                    if self.histfile and self.histvar:
                        histfile = os.path.expanduser(self.histfile)
                        if os.path.exists(histfile):
                            executor.setenv(self.histvar, histfile)
                else:
                    if config.warn("shell_startup"):
                        print_warning(
                            "WARNING: Could not configure environment from "
                            "within the target shell (%s); this has been done "
                            "in the parent process instead." % self.name())
                    executor.source(context_file)

        if shell_command:  # an empty string means 'run no command and exit'
            executor.command(shell_command)
        executor.command("exit %s" % self.last_command_status)

        code = executor.get_output()
        target_file = os.path.join(tmpdir, "rez-shell.%s" % self.file_extension())
        with open(target_file, 'w') as f:
            f.write(code)

        if d["stdin"] and stdin and (stdin is not True):
            Popen_args["stdin"] = stdin

        cmd = []
        if pre_command:
            if isinstance(pre_command, basestring):
                cmd = pre_command.strip().split()
            else:
                cmd = pre_command
        cmd.extend([self.executable, target_file])

        try:
            p = popen(cmd, env=env, **Popen_args)
        except Exception as e:
            cmd_str = ' '.join(map(pipes.quote, cmd))
            raise RezSystemError("Error running command:\n%s\n%s"
                                 % (cmd_str, str(e)))
        return p