📄 shell.py
字号:
def write(self, data): return os.read(self.fd, data) def fileno(self): return self.fd def popen(self, cmd, args, mode, capture_err=1, dir = None): # flush the stdio buffers since we are about to change the # FD under them sys.stdout.flush() sys.stderr.flush() r, w = os.pipe() pid = os.fork() if pid: # in the parent # close the descriptor that we don't need and return the other one. if mode == 'r': os.close(w) return self._pipe(r, pid) else: os.close(r) return self._pipe(w, pid) # in the child # we'll need /dev/null for the discarded I/O try: null = os.open('/dev/null', os.O_RDWR) except os.error, e: raise error, 'cannot open "/dev/null" os.error="%s"' % (str(e)) if mode == 'r': # hook stdout/stderr to the "write" channel os.dup2(w, 1) # "close" stdin; the child shouldn't use it # this isn't quite right... we may want the child to # read from stdin os.dup2(null, 0) # what to do with errors? if capture_err: os.dup2(w, 2) else: os.dup2(null, 2) else: # hook stdin to the "read" channel os.dup2(r, 0) # "close" stdout/stderr; the child shouldn't use them # this isn't quite right... we may want the child to write to these os.dup2(null, 1) os.dup2(null, 2) # don't need these FDs any more os.close(null) os.close(r) os.close(w) if dir: os.chdir(dir) # the stdin/stdout/stderr are all set up. exec the target try: os.execvp(cmd, (cmd,) + tuple(args)) except: pass # crap. shouldn't be here. os._exit(127) def run(self, command, line_cb, timeout_seconds, dir = None): import errno status = 0 list = [ "/bin/sh","-c",command ] pipe = self.popen(list[0], list[1:], "r", 1, dir) output = "" line_buff = "" timeout_time = time.time() + timeout_seconds while 1: timeout = timeout_time - time.time() if timeout < 0: pipe.kill() raise error, 'shell.run() timeout on pid="%s"' % ( pipe.child_pid) try: rlist, wlist, elist = select.select([pipe], [], [], timeout) except select.error, e: if e[0] == errno.EINTR: continue output = output + "\n BUILD WARNING, output truncated by select error %d \n" % e[0] break if pipe in rlist: try: temp = pipe.read(8192) except OSError, e: if e.errno == errno.EINTR: continue output = output + "\n BUILD WARNING, output truncated by read error %d \n" % e.errno break if temp: output = output + temp else: break if line_cb: line_buff = line_buff + temp while 1: i = string.find(line_buff, "\n") if i == -1: break i = i + 1 line_cb(line_buff[:i]) line_buff = line_buff[i:] status = pipe.close() return status, outputclass WinShellUtilities(ShellUtilities): passclass Win9xShellUtilities(WinShellUtilities): def run(self, command, line_cb, timeout_seconds, dir=None): old_dir=os.getcwd() try: if dir: os.chdir(dir) status = os.system(command) finally: os.chdir(old_dir) return status, ""class WinNTShellUtilities(WinShellUtilities): def _popen(self, command, mode, dir=None): command = "%s 2>&1" % (command) return WinShellUtilities._popen(self, command, mode, dir)class WinNTExtendedShellUtilities(WinNTShellUtilities): thread_safe=1 def _launch_idle_process(self, command_line, dir=None): saAttr = win32security.SECURITY_ATTRIBUTES() saAttr.bInheritHandle = 1 (hChildStdinRd, hChildStdinWr) = win32pipe.CreatePipe(saAttr, 0) (hChildStdoutRd, hChildStdoutWr) = win32pipe.CreatePipe(saAttr, 0) startupinfo = win32process.STARTUPINFO() startupinfo.dwFlags = \ win32process.STARTF_USESTDHANDLES | \ win32process.STARTF_USESHOWWINDOW; startupinfo.hStdInput = hChildStdinRd; startupinfo.hStdOutput = hChildStdoutWr; startupinfo.hStdError = hChildStdoutWr; appName = None commandLine = command_line processAttributes = None threadAttributes = None bInheritHandles = 1 dwCreationFlags = win32process.IDLE_PRIORITY_CLASS newEnvironment = os.environ currentDirectory = None if dir: currentDirectory = os.path.normpath(os.path.join(os.getcwd(), dir)) ## no dialog boxes that hang the build system SEM_FAILCRITICALERRORS = 0x0001 SEM_NOGPFAULTERRORBOX = 0x0002 SEM_NOALIGNMENTFAULTEXCEPT = 0x0004 SEM_NOOPENFILEERRORBOX = 0x8000 win32api.SetErrorMode( SEM_FAILCRITICALERRORS|\ SEM_NOGPFAULTERRORBOX|\ SEM_NOOPENFILEERRORBOX) try: (hProcess, hThread, dwProcessId, dwThreadId) = \ win32process.CreateProcess( appName, commandLine, processAttributes, threadAttributes, bInheritHandles, dwCreationFlags, newEnvironment, currentDirectory, startupinfo) except pywintypes.error: return None ## close the thread handle, as well as the other I/O handles win32api.CloseHandle(hThread) win32api.CloseHandle(hChildStdinRd) win32api.CloseHandle(hChildStdoutWr) return hProcess, hChildStdinWr, hChildStdoutRd def run(self, command, line_cb, timeout_seconds, dir = None): ## when _lanuch_idle_process fails, it returns None which ## will raise a TypeError from the tuple-assignment try: (hProcess, hChildStdinWr, hChildStdoutRd) = \ self._launch_idle_process(command, dir) except TypeError: return 1, "" ## get the output of the command output = "" line_buff = "" while 1: try: r = win32event.WaitForSingleObject( hChildStdoutRd, win32event.INFINITE) except pywintypes.error: break if r == win32event.WAIT_FAILED: break if r == win32event.WAIT_ABANDONED: break try: n, temp = win32file.ReadFile(hChildStdoutRd, 1, None) except IndexError: break except pywintypes.error: break output = output + temp if line_cb: line_buff = line_buff + temp while 1: i = string.find(line_buff, "\n") if i == -1: break i = i + 1 line_cb(line_buff[:i]) line_buff = line_buff[i:] ## get the exit status of the command while 1: status = win32process.GetExitCodeProcess(hProcess) if status != 259: break time.sleep(0.1) return status, outputBaseMacShellUtilities=ShellUtilitiesif os.name == 'mac' and os.environ.get("FAKE_MAC","no") == "YES": BaseMacShellUtilities=UNIXShellUtilitiesclass MacShellUtilities(BaseMacShellUtilities): ## Please do not use!!! def _make_path_relative(self, path): if not path: return if path[0] != os.sep: path = '%s%s' % (os.sep, path) return path def _platform_cp(self, source_path, destination_path): ## copy file data source = self._open(source_path, 'rb') destination = self._open(destination_path, 'wb') self._raw_copy(source, destination) source.close() destination.close() ## copy resource file data source = MacOS.openrf(source_path, '*rb') destination = MacOS.openrf(destination_path, '*wb') self._raw_copy(source, destination) source.close() destination.close() ## set creator/type on the Macintosh source_spec = macfs.FSSpec(source_path) (creator, type) = source_spec.GetCreatorType() destination_spec = macfs.FSSpec(destination_path) destination_spec.SetCreatorType(creator, type) ## copy file mode/time bits st = os.stat(source_path) mtime = st[stat.ST_MTIME] destination_spec.SetDates(mtime, mtime, mtime)## instance of shell utilities based on platform_shell = Noneif os.name == "mac": _shell = MacShellUtilities()elif os.name == "posix": _shell = UNIXShellUtilities()elif os.name == "nt" and os.environ.get('OS') == 'Windows_NT': if win32api: _shell = WinNTExtendedShellUtilities() else: _shell = WinNTShellUtilities()elif os.name == "dos" or \ string.find(os.environ.get("winbootdir", ""), "WINDOWS") >= 0: _shell = Win9xShellUtilities()else: raise error, "unsupported platform for shell.py"## entry pointsdef rm(path): """Given a path, recursively remove it.""" _shell.rm(path)def cp(source_path, destination_path): """Copy a file from source_path to destination_path.""" _shell.cp(source_path, destination_path)def cpdir(source_path, destination_path): """Recursively copy a source directory to a destination directory.""" _shell.cpdir(source_path, destination_path)def find(path_list): """I can't remember what this is for.""" return _shell.find(path_list)def mkdir(path): """Make the directory for the given path, recursively if needed.""" return _shell.mkdir(path)def run(command, line_cb = None, timeout_seconds = 36000, dir = None): """Run a command, capturing stdin/stdout. Terminate the process if it runs longer than timeout_seconds. Return (status, output) from the command. Callback the line_cb function upon reading each line from the command if a callback is given.""" return _shell.run(command, line_cb, timeout_seconds, dir)def isthreadsafe(): try: return _shell.thread_safe except AttributeError: return None
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -