def run_command(commands):
        # type: (Union[AnyStr, List[AnyStr]]) -> List[AnyStr]
        """Execute external command, and return the output lines list. In windows, refers to
        `handling-subprocess-crash-in-windows`_.

        Args:
            commands: string or list

        Returns:
            output lines

        .. _handling-subprocess-crash-in-windows:
            https://stackoverflow.com/questions/5069224/handling-subprocess-crash-in-windows
        """
        # commands = StringClass.convert_unicode2str(commands)
        # print(commands)

        use_shell = False
        subprocess_flags = 0
        startupinfo = None
        if sysstr == 'Windows':
            if isinstance(commands, list):
                commands = ' '.join(str(c) for c in commands)
            import ctypes
            SEM_NOGPFAULTERRORBOX = 0x0002  # From MSDN
            ctypes.windll.kernel32.SetErrorMode(SEM_NOGPFAULTERRORBOX)
            subprocess_flags = 0x8000000  # win32con.CREATE_NO_WINDOW?
            # this startupinfo structure prevents a console window from popping up on Windows
            startupinfo = subprocess.STARTUPINFO()
            startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
            # not sure if node outputs on stderr or stdout so capture both
        else:  # for Linux/Unix OS, commands is better to be a list.
            if is_string(commands):
                use_shell = True
                # https://docs.python.org/2/library/subprocess.html
                #     Using shell=True can be a security hazard.
            elif isinstance(commands, list):
                # the executable path may be enclosed with quotes, if not windows, delete the quotes
                if commands[0][0] == commands[0][-1] == '"' or \
                        commands[0][0] == commands[0][-1] == "'":
                    commands[0] = commands[0][1:-1]
                for idx, v in enumerate(commands):
                    if isinstance(v, int) or isinstance(v, float):
                        # Fix :TypeError: execv() arg 2 must contain only strings
                        commands[idx] = repr(v)
        print(commands)
        process = subprocess.Popen(commands, shell=use_shell, stdout=subprocess.PIPE,
                                   stdin=open(os.devnull),
                                   stderr=subprocess.STDOUT, universal_newlines=True,
                                   startupinfo=startupinfo,
                                   creationflags=subprocess_flags)
        out, err = process.communicate()
        recode = process.returncode

        if out is None:
            return ['']
        if recode is not None and recode != 0:
            raise subprocess.CalledProcessError(-1, commands,
                                                "ERROR occurred when running subprocess!")
        if '\n' in out:
            return out.split('\n')

        return [out]
Execute external command, and return the output lines list. In windows, refers to
        `handling-subprocess-crash-in-windows`_.

        Args:
            commands: string or list

        Returns:
            output lines

        .. _handling-subprocess-crash-in-windows:
            https://stackoverflow.com/questions/5069224/handling-subprocess-crash-in-windows