def test_unicode(self): # Unicode interface u = u'abc€þ¾½³ð' p = pexpect.spawn('cat') p.sendline(u) p.expect(u) # Bytes interface u = u.encode('utf-8') pb = pexpect.spawnb('cat') p.sendline(u) p.expect(u)
def system(self, cmd, output=False, handle=None): enc = DEFAULT_ENCODING patterns = [pexpect.TIMEOUT, pexpect.EOF] EOF_index = patterns.index(pexpect.EOF) out_size = 0 out = '' try: if hasattr(pexpect, 'spawnb'): child = pexpect.spawnb(self.sh, args=['-c', cmd]) # Pexpect-U else: child = pexpect.spawn(self.sh, args=['-c', cmd]) # Vanilla Pexpect if handle: handle(child) flush = sys.stdout.flush while True: res_idx = child.expect_list(patterns, self.read_timeout) line = child.before[out_size:].decode(enc, 'replace') if output: out += line print(line, end='') flush() if res_idx == EOF_index: break out_size = len(child.before) except KeyboardInterrupt: child.sendline(chr(3)) try: out_size = len(child.before) child.expect_list(patterns, self.terminate_timeout) line = child.before[out_size:].decode(enc, 'replace') if output: out += line print(line, end='') sys.stdout.flush() except KeyboardInterrupt: pass finally: child.terminate(force=True) child.isalive() if child.exitstatus is None: if child.signalstatus is None: return 0, out return -child.signalstatus, out if child.exitstatus > 128: return -(child.exitstatus - 128), out return child.exitstatus, out
def system(self, cmd): """Execute a command in a subshell. Parameters ---------- cmd : str A command to be executed in the system shell. Returns ------- int : child's exitstatus """ # Get likely encoding for the output. enc = DEFAULT_ENCODING # Patterns to match on the output, for pexpect. We read input and # allow either a short timeout or EOF patterns = [pexpect.TIMEOUT, pexpect.EOF] # the index of the EOF pattern in the list. # even though we know it's 1, this call means we don't have to worry if # we change the above list, and forget to change this value: EOF_index = patterns.index(pexpect.EOF) # The size of the output stored so far in the process output buffer. # Since pexpect only appends to this buffer, each time we print we # record how far we've printed, so that next time we only print *new* # content from the buffer. out_size = 0 try: # Since we're not really searching the buffer for text patterns, we # can set pexpect's search window to be tiny and it won't matter. # We only search for the 'patterns' timeout or EOF, which aren't in # the text itself. #child = pexpect.spawn(pcmd, searchwindowsize=1) if hasattr(pexpect, 'spawnb'): child = pexpect.spawnb(self.sh, args=['-c', cmd]) # Pexpect-U else: child = pexpect.spawn(self.sh, args=['-c', cmd]) # Vanilla Pexpect flush = sys.stdout.flush while True: # res is the index of the pattern that caused the match, so we # know whether we've finished (if we matched EOF) or not res_idx = child.expect_list(patterns, self.read_timeout) print(child.before[out_size:].decode(enc, 'replace'), end='') flush() if res_idx==EOF_index: break # Update the pointer to what we've already printed out_size = len(child.before) except KeyboardInterrupt: # We need to send ^C to the process. The ascii code for '^C' is 3 # (the character is known as ETX for 'End of Text', see # curses.ascii.ETX). child.sendline(chr(3)) # Read and print any more output the program might produce on its # way out. try: out_size = len(child.before) child.expect_list(patterns, self.terminate_timeout) print(child.before[out_size:].decode(enc, 'replace'), end='') sys.stdout.flush() except KeyboardInterrupt: # Impatient users tend to type it multiple times pass finally: # Ensure the subprocess really is terminated child.terminate(force=True) # add isalive check, to ensure exitstatus is set: child.isalive() # We follow the subprocess pattern, returning either the exit status # as a positive number, or the terminating signal as a negative # number. # on Linux, sh returns 128+n for signals terminating child processes on Linux # on BSD (OS X), the signal code is set instead if child.exitstatus is None: # on WIFSIGNALED, pexpect sets signalstatus, leaving exitstatus=None if child.signalstatus is None: # this condition may never occur, # but let's be certain we always return an integer. return 0 return -child.signalstatus if child.exitstatus > 128: return -(child.exitstatus - 128) return child.exitstatus
def system(self, cmd): """Execute a command in a subshell. Parameters ---------- cmd : str A command to be executed in the system shell. Returns ------- int : child's exitstatus """ # Get likely encoding for the output. enc = DEFAULT_ENCODING # Patterns to match on the output, for pexpect. We read input and # allow either a short timeout or EOF patterns = [pexpect.TIMEOUT, pexpect.EOF] # the index of the EOF pattern in the list. # even though we know it's 1, this call means we don't have to worry if # we change the above list, and forget to change this value: EOF_index = patterns.index(pexpect.EOF) # The size of the output stored so far in the process output buffer. # Since pexpect only appends to this buffer, each time we print we # record how far we've printed, so that next time we only print *new* # content from the buffer. out_size = 0 try: # Since we're not really searching the buffer for text patterns, we # can set pexpect's search window to be tiny and it won't matter. # We only search for the 'patterns' timeout or EOF, which aren't in # the text itself. #child = pexpect.spawn(pcmd, searchwindowsize=1) if hasattr(pexpect, 'spawnb'): child = pexpect.spawnb(self.sh, args=['-c', cmd]) # Pexpect-U else: child = pexpect.spawn(self.sh, args=['-c', cmd]) # Vanilla Pexpect flush = sys.stdout.flush while True: # res is the index of the pattern that caused the match, so we # know whether we've finished (if we matched EOF) or not res_idx = child.expect_list(patterns, self.read_timeout) print(child.before[out_size:].decode(enc, 'replace'), end='') flush() if res_idx == EOF_index: break # Update the pointer to what we've already printed out_size = len(child.before) except KeyboardInterrupt: # We need to send ^C to the process. The ascii code for '^C' is 3 # (the character is known as ETX for 'End of Text', see # curses.ascii.ETX). child.sendline(chr(3)) # Read and print any more output the program might produce on its # way out. try: out_size = len(child.before) child.expect_list(patterns, self.terminate_timeout) print(child.before[out_size:].decode(enc, 'replace'), end='') sys.stdout.flush() except KeyboardInterrupt: # Impatient users tend to type it multiple times pass finally: # Ensure the subprocess really is terminated child.terminate(force=True) # add isalive check, to ensure exitstatus is set: child.isalive() # We follow the subprocess pattern, returning either the exit status # as a positive number, or the terminating signal as a negative # number. # on Linux, sh returns 128+n for signals terminating child processes on Linux # on BSD (OS X), the signal code is set instead if child.exitstatus is None: # on WIFSIGNALED, pexpect sets signalstatus, leaving exitstatus=None if child.signalstatus is None: # this condition may never occur, # but let's be certain we always return an integer. return 0 return -child.signalstatus if child.exitstatus > 128: return -(child.exitstatus - 128) return child.exitstatus