diff options
author | Noah Spurrier <noah@squaretrade.com> | 2012-10-26 11:19:10 -0700 |
---|---|---|
committer | Noah Spurrier <noah@squaretrade.com> | 2012-10-26 11:19:10 -0700 |
commit | 7999ca657997e78febfb3fb89cfcc066d50bf788 (patch) | |
tree | 7ff33465bb4f8f79b92add505d11d4b731dfe6a7 /pexpect | |
parent | 6b65a76c26d72caf0a5b11725750861bf89f2b75 (diff) | |
download | pexpect-git-7999ca657997e78febfb3fb89cfcc066d50bf788.tar.gz |
Moved everything up one directory level.
Diffstat (limited to 'pexpect')
106 files changed, 0 insertions, 15102 deletions
diff --git a/pexpect/ANSI.py b/pexpect/ANSI.py deleted file mode 100644 index 99b7743..0000000 --- a/pexpect/ANSI.py +++ /dev/null @@ -1,368 +0,0 @@ -'''This implements an ANSI (VT100) terminal emulator as a subclass of screen. - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -# references: -# http://en.wikipedia.org/wiki/ANSI_escape_code -# http://www.retards.org/terminals/vt102.html -# http://vt100.net/docs/vt102-ug/contents.html -# http://vt100.net/docs/vt220-rm/ -# http://www.termsys.demon.co.uk/vtansi.htm - -import screen -import FSM -import copy -import string - -# -# The 'Do.*' functions are helper functions for the ANSI class. -# -def DoEmit (fsm): - - screen = fsm.memory[0] - screen.write_ch(fsm.input_symbol) - -def DoStartNumber (fsm): - - fsm.memory.append (fsm.input_symbol) - -def DoBuildNumber (fsm): - - ns = fsm.memory.pop() - ns = ns + fsm.input_symbol - fsm.memory.append (ns) - -def DoBackOne (fsm): - - screen = fsm.memory[0] - screen.cursor_back () - -def DoBack (fsm): - - count = int(fsm.memory.pop()) - screen = fsm.memory[0] - screen.cursor_back (count) - -def DoDownOne (fsm): - - screen = fsm.memory[0] - screen.cursor_down () - -def DoDown (fsm): - - count = int(fsm.memory.pop()) - screen = fsm.memory[0] - screen.cursor_down (count) - -def DoForwardOne (fsm): - - screen = fsm.memory[0] - screen.cursor_forward () - -def DoForward (fsm): - - count = int(fsm.memory.pop()) - screen = fsm.memory[0] - screen.cursor_forward (count) - -def DoUpReverse (fsm): - - screen = fsm.memory[0] - screen.cursor_up_reverse() - -def DoUpOne (fsm): - - screen = fsm.memory[0] - screen.cursor_up () - -def DoUp (fsm): - - count = int(fsm.memory.pop()) - screen = fsm.memory[0] - screen.cursor_up (count) - -def DoHome (fsm): - - c = int(fsm.memory.pop()) - r = int(fsm.memory.pop()) - screen = fsm.memory[0] - screen.cursor_home (r,c) - -def DoHomeOrigin (fsm): - - c = 1 - r = 1 - screen = fsm.memory[0] - screen.cursor_home (r,c) - -def DoEraseDown (fsm): - - screen = fsm.memory[0] - screen.erase_down() - -def DoErase (fsm): - - arg = int(fsm.memory.pop()) - screen = fsm.memory[0] - if arg == 0: - screen.erase_down() - elif arg == 1: - screen.erase_up() - elif arg == 2: - screen.erase_screen() - -def DoEraseEndOfLine (fsm): - - screen = fsm.memory[0] - screen.erase_end_of_line() - -def DoEraseLine (fsm): - - arg = int(fsm.memory.pop()) - screen = fsm.memory[0] - if arg == 0: - screen.erase_end_of_line() - elif arg == 1: - screen.erase_start_of_line() - elif arg == 2: - screen.erase_line() - -def DoEnableScroll (fsm): - - screen = fsm.memory[0] - screen.scroll_screen() - -def DoCursorSave (fsm): - - screen = fsm.memory[0] - screen.cursor_save_attrs() - -def DoCursorRestore (fsm): - - screen = fsm.memory[0] - screen.cursor_restore_attrs() - -def DoScrollRegion (fsm): - - screen = fsm.memory[0] - r2 = int(fsm.memory.pop()) - r1 = int(fsm.memory.pop()) - screen.scroll_screen_rows (r1,r2) - -def DoMode (fsm): - - screen = fsm.memory[0] - mode = fsm.memory.pop() # Should be 4 - # screen.setReplaceMode () - -def DoLog (fsm): - - screen = fsm.memory[0] - fsm.memory = [screen] - fout = open ('log', 'a') - fout.write (fsm.input_symbol + ',' + fsm.current_state + '\n') - fout.close() - -class term (screen.screen): - - '''This class is an abstract, generic terminal. - This does nothing. This is a placeholder that - provides a common base class for other terminals - such as an ANSI terminal. ''' - - def __init__ (self, r=24, c=80): - - screen.screen.__init__(self, r,c) - -class ANSI (term): - - '''This class implements an ANSI (VT100) terminal. - It is a stream filter that recognizes ANSI terminal - escape sequences and maintains the state of a screen object. ''' - - def __init__ (self, r=24,c=80): - - term.__init__(self,r,c) - - #self.screen = screen (24,80) - self.state = FSM.FSM ('INIT',[self]) - self.state.set_default_transition (DoLog, 'INIT') - self.state.add_transition_any ('INIT', DoEmit, 'INIT') - self.state.add_transition ('\x1b', 'INIT', None, 'ESC') - self.state.add_transition_any ('ESC', DoLog, 'INIT') - self.state.add_transition ('(', 'ESC', None, 'G0SCS') - self.state.add_transition (')', 'ESC', None, 'G1SCS') - self.state.add_transition_list ('AB012', 'G0SCS', None, 'INIT') - self.state.add_transition_list ('AB012', 'G1SCS', None, 'INIT') - self.state.add_transition ('7', 'ESC', DoCursorSave, 'INIT') - self.state.add_transition ('8', 'ESC', DoCursorRestore, 'INIT') - self.state.add_transition ('M', 'ESC', DoUpReverse, 'INIT') - self.state.add_transition ('>', 'ESC', DoUpReverse, 'INIT') - self.state.add_transition ('<', 'ESC', DoUpReverse, 'INIT') - self.state.add_transition ('=', 'ESC', None, 'INIT') # Selects application keypad. - self.state.add_transition ('#', 'ESC', None, 'GRAPHICS_POUND') - self.state.add_transition_any ('GRAPHICS_POUND', None, 'INIT') - self.state.add_transition ('[', 'ESC', None, 'ELB') - # ELB means Escape Left Bracket. That is ^[[ - self.state.add_transition ('H', 'ELB', DoHomeOrigin, 'INIT') - self.state.add_transition ('D', 'ELB', DoBackOne, 'INIT') - self.state.add_transition ('B', 'ELB', DoDownOne, 'INIT') - self.state.add_transition ('C', 'ELB', DoForwardOne, 'INIT') - self.state.add_transition ('A', 'ELB', DoUpOne, 'INIT') - self.state.add_transition ('J', 'ELB', DoEraseDown, 'INIT') - self.state.add_transition ('K', 'ELB', DoEraseEndOfLine, 'INIT') - self.state.add_transition ('r', 'ELB', DoEnableScroll, 'INIT') - self.state.add_transition ('m', 'ELB', None, 'INIT') - self.state.add_transition ('?', 'ELB', None, 'MODECRAP') - self.state.add_transition_list (string.digits, 'ELB', DoStartNumber, 'NUMBER_1') - self.state.add_transition_list (string.digits, 'NUMBER_1', DoBuildNumber, 'NUMBER_1') - self.state.add_transition ('D', 'NUMBER_1', DoBack, 'INIT') - self.state.add_transition ('B', 'NUMBER_1', DoDown, 'INIT') - self.state.add_transition ('C', 'NUMBER_1', DoForward, 'INIT') - self.state.add_transition ('A', 'NUMBER_1', DoUp, 'INIT') - self.state.add_transition ('J', 'NUMBER_1', DoErase, 'INIT') - self.state.add_transition ('K', 'NUMBER_1', DoEraseLine, 'INIT') - self.state.add_transition ('l', 'NUMBER_1', DoMode, 'INIT') - ### It gets worse... the 'm' code can have infinite number of - ### number;number;number before it. I've never seen more than two, - ### but the specs say it's allowed. crap! - self.state.add_transition ('m', 'NUMBER_1', None, 'INIT') - ### LED control. Same implementation problem as 'm' code. - self.state.add_transition ('q', 'NUMBER_1', None, 'INIT') - - # \E[?47h switch to alternate screen - # \E[?47l restores to normal screen from alternate screen. - self.state.add_transition_list (string.digits, 'MODECRAP', DoStartNumber, 'MODECRAP_NUM') - self.state.add_transition_list (string.digits, 'MODECRAP_NUM', DoBuildNumber, 'MODECRAP_NUM') - self.state.add_transition ('l', 'MODECRAP_NUM', None, 'INIT') - self.state.add_transition ('h', 'MODECRAP_NUM', None, 'INIT') - -#RM Reset Mode Esc [ Ps l none - self.state.add_transition (';', 'NUMBER_1', None, 'SEMICOLON') - self.state.add_transition_any ('SEMICOLON', DoLog, 'INIT') - self.state.add_transition_list (string.digits, 'SEMICOLON', DoStartNumber, 'NUMBER_2') - self.state.add_transition_list (string.digits, 'NUMBER_2', DoBuildNumber, 'NUMBER_2') - self.state.add_transition_any ('NUMBER_2', DoLog, 'INIT') - self.state.add_transition ('H', 'NUMBER_2', DoHome, 'INIT') - self.state.add_transition ('f', 'NUMBER_2', DoHome, 'INIT') - self.state.add_transition ('r', 'NUMBER_2', DoScrollRegion, 'INIT') - ### It gets worse... the 'm' code can have infinite number of - ### number;number;number before it. I've never seen more than two, - ### but the specs say it's allowed. crap! - self.state.add_transition ('m', 'NUMBER_2', None, 'INIT') - ### LED control. Same problem as 'm' code. - self.state.add_transition ('q', 'NUMBER_2', None, 'INIT') - self.state.add_transition (';', 'NUMBER_2', None, 'SEMICOLON_X') - - # Create a state for 'q' and 'm' which allows an infinite number of ignored numbers - self.state.add_transition_any ('SEMICOLON_X', DoLog, 'INIT') - self.state.add_transition_list (string.digits, 'SEMICOLON_X', None, 'NUMBER_X') - self.state.add_transition_any ('NUMBER_X', DoLog, 'INIT') - self.state.add_transition ('m', 'NUMBER_X', None, 'INIT') - self.state.add_transition ('q', 'NUMBER_X', None, 'INIT') - self.state.add_transition (';', 'NUMBER_2', None, 'SEMICOLON_X') - - def process (self, c): - - self.state.process(c) - - def process_list (self, l): - - self.write(l) - - def write (self, s): - - for c in s: - self.process(c) - - def flush (self): - - pass - - def write_ch (self, ch): - - '''This puts a character at the current cursor position. The cursor - position is moved forward with wrap-around, but no scrolling is done if - the cursor hits the lower-right corner of the screen. ''' - - #\r and \n both produce a call to cr() and lf(), respectively. - ch = ch[0] - - if ch == '\r': - self.cr() - return - if ch == '\n': - self.crlf() - return - if ch == chr(screen.BS): - self.cursor_back() - return - if ch not in string.printable: - fout = open ('log', 'a') - fout.write ('Nonprint: ' + str(ord(ch)) + '\n') - fout.close() - return - self.put_abs(self.cur_r, self.cur_c, ch) - old_r = self.cur_r - old_c = self.cur_c - self.cursor_forward() - if old_c == self.cur_c: - self.cursor_down() - if old_r != self.cur_r: - self.cursor_home (self.cur_r, 1) - else: - self.scroll_up () - self.cursor_home (self.cur_r, 1) - self.erase_line() - -# def test (self): -# -# import sys -# write_text = 'I\'ve got a ferret sticking up my nose.\n' + \ -# '(He\'s got a ferret sticking up his nose.)\n' + \ -# 'How it got there I can\'t tell\n' + \ -# 'But now it\'s there it hurts like hell\n' + \ -# 'And what is more it radically affects my sense of smell.\n' + \ -# '(His sense of smell.)\n' + \ -# 'I can see a bare-bottomed mandril.\n' + \ -# '(Slyly eyeing his other nostril.)\n' + \ -# 'If it jumps inside there too I really don\'t know what to do\n' + \ -# 'I\'ll be the proud posessor of a kind of nasal zoo.\n' + \ -# '(A nasal zoo.)\n' + \ -# 'I\'ve got a ferret sticking up my nose.\n' + \ -# '(And what is worst of all it constantly explodes.)\n' + \ -# '"Ferrets don\'t explode," you say\n' + \ -# 'But it happened nine times yesterday\n' + \ -# 'And I should know for each time I was standing in the way.\n' + \ -# 'I\'ve got a ferret sticking up my nose.\n' + \ -# '(He\'s got a ferret sticking up his nose.)\n' + \ -# 'How it got there I can\'t tell\n' + \ -# 'But now it\'s there it hurts like hell\n' + \ -# 'And what is more it radically affects my sense of smell.\n' + \ -# '(His sense of smell.)' -# self.fill('.') -# self.cursor_home() -# for c in write_text: -# self.write_ch (c) -# print str(self) -# -#if __name__ == '__main__': -# t = ANSI(6,65) -# t.test() diff --git a/pexpect/DEVELOPERS b/pexpect/DEVELOPERS deleted file mode 100644 index 8f9aa43..0000000 --- a/pexpect/DEVELOPERS +++ /dev/null @@ -1,52 +0,0 @@ - -To edit and test code and to run the Pyunit tests you need to source the -environment file provided in the root of the development directory. -For example: - - . test.env - -Then to run unit tests run the testall.py script under the tools/ directory. -For example: - - ./tools/testall.py - -The test.env environment file sets the PYTHONPATH to the Pexpect development -root directory. This way the unit tests and python interpreter will import the -development version of Pexpect instead of any older versions that you may have -installed on the system. - -The Pyunit tests are all located in the tests/ directory. To add a new unit -test all you have to do is create the file in the tests/ directory with a -filename in this format: - - test_*.py - -The testall.py script in the tools/ directory will automatically add all -test_*.py files to the test suite. To create a new unit test follow the example -of one of the other test_*.py scripts. Basically, a new unit test will follow -this template: - -<pre> -#!/usr/bin/env python -import pexpect -import unittest -import PexpectTestCase - -# 1. Derive your test case class from PexpectTestCase.PexpectTestCase. -# 2. At the end of this script add your test case class to the suite using -# unittest.MakeSuite. -# 3. All test case methods should be named like test_*. -class TestCaseFoo (PexpectTestCase.PexpectTestCase): - - def test_case (self): - assert (False), "This is an example template." - - def test_case_something_else (self): - assert (False), "This is an example template." - -if __name__ == '__main__': - unittest.main() - -suite = unittest.makeSuite(TestCaseFoo,'test') -</pre> - diff --git a/pexpect/FSM.py b/pexpect/FSM.py deleted file mode 100644 index ad22880..0000000 --- a/pexpect/FSM.py +++ /dev/null @@ -1,346 +0,0 @@ -#!/usr/bin/env python - -'''This module implements a Finite State Machine (FSM). In addition to state -this FSM also maintains a user defined "memory". So this FSM can be used as a -Push-down Automata (PDA) since a PDA is a FSM + memory. - -The following describes how the FSM works, but you will probably also need to -see the example function to understand how the FSM is used in practice. - -You define an FSM by building tables of transitions. For a given input symbol -the process() method uses these tables to decide what action to call and what -the next state will be. The FSM has a table of transitions that associate: - - (input_symbol, current_state) --> (action, next_state) - -Where "action" is a function you define. The symbols and states can be any -objects. You use the add_transition() and add_transition_list() methods to add -to the transition table. The FSM also has a table of transitions that -associate: - - (current_state) --> (action, next_state) - -You use the add_transition_any() method to add to this transition table. The -FSM also has one default transition that is not associated with any specific -input_symbol or state. You use the set_default_transition() method to set the -default transition. - -When an action function is called it is passed a reference to the FSM. The -action function may then access attributes of the FSM such as input_symbol, -current_state, or "memory". The "memory" attribute can be any object that you -want to pass along to the action functions. It is not used by the FSM itself. -For parsing you would typically pass a list to be used as a stack. - -The processing sequence is as follows. The process() method is given an -input_symbol to process. The FSM will search the table of transitions that -associate: - - (input_symbol, current_state) --> (action, next_state) - -If the pair (input_symbol, current_state) is found then process() will call the -associated action function and then set the current state to the next_state. - -If the FSM cannot find a match for (input_symbol, current_state) it will then -search the table of transitions that associate: - - (current_state) --> (action, next_state) - -If the current_state is found then the process() method will call the -associated action function and then set the current state to the next_state. -Notice that this table lacks an input_symbol. It lets you define transitions -for a current_state and ANY input_symbol. Hence, it is called the "any" table. -Remember, it is always checked after first searching the table for a specific -(input_symbol, current_state). - -For the case where the FSM did not match either of the previous two cases the -FSM will try to use the default transition. If the default transition is -defined then the process() method will call the associated action function and -then set the current state to the next_state. This lets you define a default -transition as a catch-all case. You can think of it as an exception handler. -There can be only one default transition. - -Finally, if none of the previous cases are defined for an input_symbol and -current_state then the FSM will raise an exception. This may be desirable, but -you can always prevent this just by defining a default transition. - -Noah Spurrier 20020822 - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -class ExceptionFSM(Exception): - - '''This is the FSM Exception class.''' - - def __init__(self, value): - self.value = value - - def __str__(self): - return `self.value` - -class FSM: - - '''This is a Finite State Machine (FSM). - ''' - - def __init__(self, initial_state, memory=None): - - '''This creates the FSM. You set the initial state here. The "memory" - attribute is any object that you want to pass along to the action - functions. It is not used by the FSM. For parsing you would typically - pass a list to be used as a stack. ''' - - # Map (input_symbol, current_state) --> (action, next_state). - self.state_transitions = {} - # Map (current_state) --> (action, next_state). - self.state_transitions_any = {} - self.default_transition = None - - self.input_symbol = None - self.initial_state = initial_state - self.current_state = self.initial_state - self.next_state = None - self.action = None - self.memory = memory - - def reset (self): - - '''This sets the current_state to the initial_state and sets - input_symbol to None. The initial state was set by the constructor - __init__(). ''' - - self.current_state = self.initial_state - self.input_symbol = None - - def add_transition (self, input_symbol, state, action=None, next_state=None): - - '''This adds a transition that associates: - - (input_symbol, current_state) --> (action, next_state) - - The action may be set to None in which case the process() method will - ignore the action and only set the next_state. The next_state may be - set to None in which case the current state will be unchanged. - - You can also set transitions for a list of symbols by using - add_transition_list(). ''' - - if next_state is None: - next_state = state - self.state_transitions[(input_symbol, state)] = (action, next_state) - - def add_transition_list (self, list_input_symbols, state, action=None, next_state=None): - - '''This adds the same transition for a list of input symbols. - You can pass a list or a string. Note that it is handy to use - string.digits, string.whitespace, string.letters, etc. to add - transitions that match character classes. - - The action may be set to None in which case the process() method will - ignore the action and only set the next_state. The next_state may be - set to None in which case the current state will be unchanged. ''' - - if next_state is None: - next_state = state - for input_symbol in list_input_symbols: - self.add_transition (input_symbol, state, action, next_state) - - def add_transition_any (self, state, action=None, next_state=None): - - '''This adds a transition that associates: - - (current_state) --> (action, next_state) - - That is, any input symbol will match the current state. - The process() method checks the "any" state associations after it first - checks for an exact match of (input_symbol, current_state). - - The action may be set to None in which case the process() method will - ignore the action and only set the next_state. The next_state may be - set to None in which case the current state will be unchanged. ''' - - if next_state is None: - next_state = state - self.state_transitions_any [state] = (action, next_state) - - def set_default_transition (self, action, next_state): - - '''This sets the default transition. This defines an action and - next_state if the FSM cannot find the input symbol and the current - state in the transition list and if the FSM cannot find the - current_state in the transition_any list. This is useful as a final - fall-through state for catching errors and undefined states. - - The default transition can be removed by setting the attribute - default_transition to None. ''' - - self.default_transition = (action, next_state) - - def get_transition (self, input_symbol, state): - - '''This returns (action, next state) given an input_symbol and state. - This does not modify the FSM state, so calling this method has no side - effects. Normally you do not call this method directly. It is called by - process(). - - The sequence of steps to check for a defined transition goes from the - most specific to the least specific. - - 1. Check state_transitions[] that match exactly the tuple, - (input_symbol, state) - - 2. Check state_transitions_any[] that match (state) - In other words, match a specific state and ANY input_symbol. - - 3. Check if the default_transition is defined. - This catches any input_symbol and any state. - This is a handler for errors, undefined states, or defaults. - - 4. No transition was defined. If we get here then raise an exception. - ''' - - if self.state_transitions.has_key((input_symbol, state)): - return self.state_transitions[(input_symbol, state)] - elif self.state_transitions_any.has_key (state): - return self.state_transitions_any[state] - elif self.default_transition is not None: - return self.default_transition - else: - raise ExceptionFSM ('Transition is undefined: (%s, %s).' % - (str(input_symbol), str(state)) ) - - def process (self, input_symbol): - - '''This is the main method that you call to process input. This may - cause the FSM to change state and call an action. This method calls - get_transition() to find the action and next_state associated with the - input_symbol and current_state. If the action is None then the action - is not called and only the current state is changed. This method - processes one complete input symbol. You can process a list of symbols - (or a string) by calling process_list(). ''' - - self.input_symbol = input_symbol - (self.action, self.next_state) = self.get_transition (self.input_symbol, self.current_state) - if self.action is not None: - self.action (self) - self.current_state = self.next_state - self.next_state = None - - def process_list (self, input_symbols): - - '''This takes a list and sends each element to process(). The list may - be a string or any iterable object. ''' - - for s in input_symbols: - self.process (s) - -############################################################################## -# The following is an example that demonstrates the use of the FSM class to -# process an RPN expression. Run this module from the command line. You will -# get a prompt > for input. Enter an RPN Expression. Numbers may be integers. -# Operators are * / + - Use the = sign to evaluate and print the expression. -# For example: -# -# 167 3 2 2 * * * 1 - = -# -# will print: -# -# 2003 -############################################################################## - -import sys -import os -import traceback -import time -import string - -# -# These define the actions. -# Note that "memory" is a list being used as a stack. -# - -def BeginBuildNumber (fsm): - fsm.memory.append (fsm.input_symbol) - -def BuildNumber (fsm): - s = fsm.memory.pop () - s = s + fsm.input_symbol - fsm.memory.append (s) - -def EndBuildNumber (fsm): - s = fsm.memory.pop () - fsm.memory.append (int(s)) - -def DoOperator (fsm): - ar = fsm.memory.pop() - al = fsm.memory.pop() - if fsm.input_symbol == '+': - fsm.memory.append (al + ar) - elif fsm.input_symbol == '-': - fsm.memory.append (al - ar) - elif fsm.input_symbol == '*': - fsm.memory.append (al * ar) - elif fsm.input_symbol == '/': - fsm.memory.append (al / ar) - -def DoEqual (fsm): - print str(fsm.memory.pop()) - -def Error (fsm): - print 'That does not compute.' - print str(fsm.input_symbol) - -def main(): - - '''This is where the example starts and the FSM state transitions are - defined. Note that states are strings (such as 'INIT'). This is not - necessary, but it makes the example easier to read. ''' - - f = FSM ('INIT', []) - f.set_default_transition (Error, 'INIT') - f.add_transition_any ('INIT', None, 'INIT') - f.add_transition ('=', 'INIT', DoEqual, 'INIT') - f.add_transition_list (string.digits, 'INIT', BeginBuildNumber, 'BUILDING_NUMBER') - f.add_transition_list (string.digits, 'BUILDING_NUMBER', BuildNumber, 'BUILDING_NUMBER') - f.add_transition_list (string.whitespace, 'BUILDING_NUMBER', EndBuildNumber, 'INIT') - f.add_transition_list ('+-*/', 'INIT', DoOperator, 'INIT') - - print - print 'Enter an RPN Expression.' - print 'Numbers may be integers. Operators are * / + -' - print 'Use the = sign to evaluate and print the expression.' - print 'For example: ' - print ' 167 3 2 2 * * * 1 - =' - inputstr = raw_input ('> ') - f.process_list(inputstr) - - -if __name__ == '__main__': - try: - main() - sys.exit(0) - except KeyboardInterrupt, e: # Ctrl-C - raise e - except SystemExit, e: # sys.exit() - raise e - except Exception, e: - print 'ERROR, UNEXPECTED EXCEPTION' - print str(e) - traceback.print_exc() - os._exit(1) diff --git a/pexpect/INSTALL b/pexpect/INSTALL deleted file mode 100644 index c3a2c65..0000000 --- a/pexpect/INSTALL +++ /dev/null @@ -1,48 +0,0 @@ -Installation ------------- -This is a standard Python Distutil distribution. To install simply run: - - python setup.py install - -This makes Pexpect available to any script on the machine. You need -root access to install it this way. If you do not have root access or -if you do not wish to install Pexpect so that is available to any script -then you can just copy the pexpect.py file to same directory as your script. - -Trouble on Debian and Ubuntu ----------------------------- -For some stupid reason Debian Linux does not include the distutils module -in the standard 'python' package. Instead, the distutils module is packaged -separately in the 'python-dev' package. So to add distutils back -into Python, simply use aptitude or apt-get to install 'python-dev'. -As root, run this command: - apt-get install python-dev -Why they do this is mysterious because: - - It breaks the Python model of "batteries included". - 'distutils' isn't an extra or optional module -- - it's parts of the Standard Python Library. - - The Debian 'python-dev' package is a microscopic 50K installed. - So what are they saving? - - Distutils is not only interesting to developers. Many non-development - oriented Python packages use 'distutils' to install applications. - - As far as I can tell, the package maintainers must go through - more trouble to remove 'distutils' from the standard Python - distribution than it would take just to leave it in. - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - diff --git a/pexpect/LICENSE b/pexpect/LICENSE deleted file mode 100644 index 18ff9db..0000000 --- a/pexpect/LICENSE +++ /dev/null @@ -1,17 +0,0 @@ -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - diff --git a/pexpect/MANIFEST.in b/pexpect/MANIFEST.in deleted file mode 100644 index 324e182..0000000 --- a/pexpect/MANIFEST.in +++ /dev/null @@ -1,4 +0,0 @@ -recursive-include doc * -recursive-include examples * -include README LICENSE INSTALL -include setup.py pexpect.py fdpexpect.py pxssh.py screen.py ANSI.py FSM.py diff --git a/pexpect/Makefile b/pexpect/Makefile deleted file mode 100644 index 8a1b72d..0000000 --- a/pexpect/Makefile +++ /dev/null @@ -1,83 +0,0 @@ - -# -# PEXPECT LICENSE -# -# This license is approved by the OSI and FSF as GPL-compatible. -# http://opensource.org/licenses/isc-license.txt -# -# Copyright (c) 2012, Noah Spurrier <noah@noah.org> -# PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY -# PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE -# COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# - -SHELL = /bin/sh - -VERSION=2.5 -#DOCGENERATOR= happydoc -DOCGENERATOR=pydoc -w -# This is for GNU Make. This does not work on BSD Make. -#MANIFEST_LINES := $(shell cat MANIFEST) -# This is for BSD Make. This does not work on GNU Make. -#MANIFEST_LINES != cat MANIFEST -# I hate Makefiles. - -all: merge_templates docs dist - -merge_templates: - python tools/merge_templates.py - -docs: doc/index.template.html doc/examples.html doc/clean.css doc/email.png - make clean_docs - make merge_templates - #-rm -f `ls doc/*.html | sed -e 's/doc\/index\.template\.html//' | sed -e 's/doc\/index\.html//'` - #$(DOCGENERATOR) `echo "$(MANIFEST_LINES)" | sed -e "s/\.py//g" -e "s/setup *//" -e "s/README *//"` - #mv *.html doc/ - cd doc;\ - $(DOCGENERATOR) ../pexpect.py ../pxssh.py ../fdpexpect.py ../FSM.py ../screen.py ../ANSI.py;\ - cd ..;\ -# tar zcf pexpect-doc-$(VERSION).tar.gz doc/ - -dist: dist/pexpect-$(VERSION).tar.gz - -# $(MANIFEST_LINES) - -dist/pexpect-$(VERSION).tar.gz: - rm -f *.pyc - rm -f pexpect-$(VERSION).tar.gz - rm -f dist/pexpect-$(VERSION).tar.gz - python setup.py sdist - -clean: clean_docs - -rm -f MANIFEST - -rm -rf __pycache__ - -rm -f *.pyc - -rm -f tests/*.pyc - -rm -f tools/*.pyc - -rm -f dist/*.pyc - -rm -f *.cover - -rm -f tests/*.cover - -rm -f tools/*.cover - -rm -f dist/pexpect-$(VERSION).tar.gz - -cd dist;rm -rf pexpect-$(VERSION)/ - -rm -f pexpect-$(VERSION).tar.gz - -rm -f pexpect-$(VERSION)-examples.tar.gz - -rm -f pexpect-$(VERSION)-doc.tar.gz - -rm -f python.core - -rm -f core - -rm -f setup.py - -rm -f doc/index.html - -clean_docs: - -rm -f `ls doc/*.html | sed -e 's/doc\/index\.template\.html//' | sed -e 's/doc\/examples\.html//'` - -test: - . ./test.env && ./tools/testall.py - diff --git a/pexpect/README b/pexpect/README deleted file mode 100644 index 85298c4..0000000 --- a/pexpect/README +++ /dev/null @@ -1,41 +0,0 @@ -Pexpect is a Pure Python Expect-like module - -Pexpect makes Python a better tool for controlling other applications. - -Pexpect is a pure Python module for spawning child applications; controlling -them; and responding to expected patterns in their output. Pexpect works like -Don Libes' Expect. Pexpect allows your script to spawn a child application and -control it as if a human were typing commands. - -Pexpect can be used for automating interactive applications such as ssh, ftp, -passwd, telnet, etc. It can be used to a automate setup scripts for duplicating -software package installations on different servers. It can be used for -automated software testing. Pexpect is in the spirit of Don Libes' Expect, but -Pexpect is pure Python. Unlike other Expect-like modules for Python, Pexpect -does not require TCL or Expect nor does it require C extensions to be compiled. -It should work on any platform that supports the standard Python pty module. -The Pexpect interface was designed to be easy to use. - -If you want to work with the development version of the source code then please -read the DEVELOPERS document in the root of the source code tree. - -Free, open source, and all that good stuff. -http://pexpect.sourceforge.net/ - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - diff --git a/pexpect/doc/clean.css b/pexpect/doc/clean.css deleted file mode 100644 index e8d98dd..0000000 --- a/pexpect/doc/clean.css +++ /dev/null @@ -1,103 +0,0 @@ - -body { - margin:0px; - padding:0px; - font-family:verdana, arial, helvetica, sans-serif; - color:#333; - background-color:white; - } -pre { - background: #eeeeee; - border: 1px solid #888888; - color: black; - padding: 1em; - white-space: pre; -} -h1 { - margin:5px 0px 5px 0px; - padding:0px; - font-size:20px; - line-height:28px; - font-weight:900; - color:#44f; - } -h2 { - margin:5px 0px 5px 0px; - padding:0px; - font-size:17px; - line-height:28px; - font-weight:900; - color:#226; - } -h3 { - margin:5px 0px 5px 0px; - padding:0px; - font-size:15px; - line-height:28px; - font-weight:900; - } -p -{ - margin:0px 0px 16px 0px; - font:11px/20px verdana, arial, helvetica, sans-serif; - padding:0px; -} -table -{ - font-size: 10pt; - color: #000000; -} -td{border:1px solid #999;} - -table.pymenu {color: #000000; background-color: #99ccff} -th.pymenu {color: #ffffff; background-color: #003366} - -.code -{ - font-family: "Lucida Console", monospace; font-weight: bold; - color: #007700; background-color: #eeeeee -} - -#Content>p {margin:0px;} -#Content>p+p {text-indent:30px;} - -a { - text-decoration:none; - font-weight:600; - font-family:verdana, arial, helvetica, sans-serif; - color: #900; -} -//a:link {color:#09c;} -//a x:visited {color:#07a;} -a:hover {background-color:#ee0;} - -#Header { - margin:10px 0px 10px 0px; - padding:10px 0px 10px 20px; - /* For IE5/Win's benefit height = [correct height] + [top padding] + [top and bottom border widths] */ - height:33px; /* 14px + 17px + 2px = 33px */ - border-style:solid; - border-color:black; - border-width:1px 0px; /* top and bottom borders: 1px; left and right borders: 0px */ - line-height:33px; - background-color:#eee; - height:66px; /* the correct height */ - } - -#Content { - margin:0px 210px 50px 10px; - padding:10px; - } - -#Menu { - position:absolute; - top:100px; - right:20px; - width:172px; - padding:10px; - background-color:#eee; - border:1px solid #999; // dashed #999; - line-height:17px; - width:150px; - font-size:11px; - } diff --git a/pexpect/doc/email.png b/pexpect/doc/email.png Binary files differdeleted file mode 100644 index 5111138..0000000 --- a/pexpect/doc/email.png +++ /dev/null diff --git a/pexpect/doc/examples.html b/pexpect/doc/examples.html deleted file mode 100644 index 2884a5c..0000000 --- a/pexpect/doc/examples.html +++ /dev/null @@ -1,135 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html> -<head> -<title>Pexpect - Examples</title> -<link rel="stylesheet" href="clean.css" type="text/css"> -<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> -<meta name="Author" content="Noah Spurrier"> -<meta name="Keywords" - content="pexpect, Noah Spurrier, Python, Libes, TCL, Expect, pipe, popen, pyExpect, expectpy, expect-like, expect-alike, expect like"> -<meta name="Description" content="Examples for using Pexpect."> -</head> -<body bgcolor="#ffffff" text="#000000"> -<div id="Header"> -<h1>Pexpect Examples</h1> -</div> -<div id="Content"> - -<p><span class="code">hive.py</span></p> -<p><blockquote> -This script creates SSH connections to a list of hosts that -you provide. Then you are given a command line prompt. Each -shell command that you enter is sent to all the hosts. The -response from each host is collected and printed. For example, -you could connect to a dozen different machines and reboot -them all at once. -</p></blockquote> - -<p><span class="code">script.py</span></p> -<p><blockquote> - This implements a command similar to the classic BSD -"script" command. - This will start a subshell and log all input and -output to a file. - This demonstrates the interact() method of Pexpect. -</p></blockquote> - -<p><span class="code">fix_cvs_files.py</span></p> -<p><blockquote> - This is for cleaning up binary files improperly -added to CVS. - This script scans the given path to find binary -files; - checks with CVS to see if the sticky options are set -to -kb; - finally if sticky options are not -kb then uses 'cvs -admin' to - set the -kb option. -</p></blockquote> - -<p><span class="code">ftp.py</span></p> -<p><blockquote> - This demonstrates an FTP "bookmark". - This connects to an ftp site; does a few ftp stuff; -and then gives the user - interactive control over the session. In this case -the "bookmark" is to a - directory on the OpenBSD ftp server. It puts you in -the i386 packages - directory. You can easily modify this for other -sites. - This demonstrates the interact() method of Pexpect. -</p></blockquote> - -<p><span class="code">monitor.py</span></p> -<p><blockquote> - This runs a sequence of commands on a remote host -using SSH. - It runs a simple system checks such as uptime and -free to monitor - the state of the remote host. -</p></blockquote> - -<p><span class="code">passmass.py</span></p> -<p><blockquote> - This will login to each given server and change the -password of the - given user. This demonstrates scripting logins and -passwords. -</p></blockquote> - -<p><span class="code">python.py</span></p> -<p><blockquote> - This starts the python interpreter and prints the -greeting message backwards. - It then gives the user iteractive control of Python. -It's pretty useless! -</p></blockquote> - -<p><span class="code">rippy.py</span></p> -<p><blockquote> - This is a wizard for mencoder. It greatly simplifies -the process of - ripping a DVD to Divx (mpeg4) format. It can -transcode from any - video file to another. It has options for resampling -the audio stream; - removing interlace artifacts, fitting to a target -file size, etc. - There are lots of options, but the process is simple -and easy to use. -</p></blockquote> - -<p><span class="code">sshls.py</span></p> -<p><blockquote> - This lists a directory on a remote machine. -</p></blockquote> -<p><span class="code">ssh_tunnel.py</span></p> -<p><blockquote> - This starts an SSH tunnel to a remote machine. It -monitors the connection - and restarts the tunnel if it goes down. -</p></blockquote> -<p><span class="code">uptime.py</span></p> -<p><blockquote> - This will run the uptime command and parse the -output into variables. - This demonstrates using a single regular expression -to match the output - of a command and capturing different variable in -match groups. - The grouping regular expression handles a wide variety of different -uptime formats. - </blockquote> - -<p> -<a href="http://sourceforge.net/projects/pexpect/" - title="The Pexpect project page on SourceForge.net"> <img - src="http://sourceforge.net/sflogo.php?group_id=59762&type=5" - alt="The Pexpect project page on SourceForge.net" border="0" - height="31" width="105"> </a> -</p> -</div> - -</body> -</html> diff --git a/pexpect/doc/index.template.html b/pexpect/doc/index.template.html deleted file mode 100644 index 9236df1..0000000 --- a/pexpect/doc/index.template.html +++ /dev/null @@ -1,868 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html> -<head> -<title>Pexpect - a Pure Python Expect-like module</title> -<link rel="stylesheet" href="clean.css" type="text/css"> -<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> -<meta name="Author" content="Noah Spurrier"> -<meta name="Keywords" - content="pexpect, Noah Spurrier, pypect, Python, Libes, TCL, Expect, pipe, popen, pyExpect, expectpy, expect-like, expect-alike, expect like"> -<meta name="Description" - content="Pexpect is a pure Python Expect-like module. Pexpect makes Python a better tool for controlling other applications."> -</head> -<body bgcolor="#ffffff" text="#000000"> -<div id="Header"> -<h1>Pexpect version VERSION<br> -a Pure Python Expect-like module -</h1> -</div> -<div id="Content"> -<p>Pexpect makes Python a better tool for controlling other -applications.</p> -<p>Pexpect is a pure Python module for spawning child applications; -controlling them; and responding to expected patterns in their output. -Pexpect works like Don Libes' Expect. Pexpect allows your script to -spawn a child application and control it as if a human were typing -commands.</p> -<p>Pexpect can be used for automating interactive applications such as -ssh, ftp, passwd, telnet, etc. It can be used to a automate setup -scripts for duplicating software package installations on different -servers. It can be used for automated software testing. Pexpect is in -the spirit of Don Libes' Expect, but Pexpect is pure Python. Unlike -other Expect-like modules for Python, Pexpect does not require TCL or -Expect nor does it require C extensions to be compiled. It should work -on any platform that supports the standard Python pty module. The -Pexpect interface was designed to be easy to use.</p> -<table border="0"> - <tbody> - <tr> - <td align="right" valign="top">Send questions to:</td> - <td align="left"><a href="http://www.noah.org/email/"><img - src="email.png" alt="Click to send email." border="0" height="16" - width="100"></a></td> - </tr> - </tbody> -</table> -<hr noshade="noshade" size="1"> -<h1><a name="license"></a>License: MIT style</h1> -<p> -Free, open source, and all that good stuff.<br> -<br> -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions:<br> -<br> -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software.<br> -<br> -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -USE OR OTHER DEALINGS IN THE SOFTWARE.<br> -<br> -Pexpect Copyright (c) 2008 Noah Spurrier<br> -http://pexpect.sourceforge.net/ -</p> - -<hr noshade="noshade" size="1"> -<h1><a name="download"></a><a - href="http://sourceforge.net/project/showfiles.php?group_id=59762">Download</a></h1> -<p>Download the <a - href="http://sourceforge.net/project/showfiles.php?group_id=59762"> -current version here</a> from the SourceForge site. Grab the current Pexpect tarball. -</p> -<h2>Installing Pexpect</h2> -<p>The Pexpect tarball is a standard Python Distutil distribution.</p> -<ol> - <li>download <span class="code">pexpect-VERSION.tar.gz</span></li> - <li><span class="code">tar zxf pexpect-VERSION.tar.gz</span></li> - <li><span class="code">cd pexpect-VERSION</span></li> - <li><span class="code">python setup.py install</span> <i>do this as root</i></li> -</ol> -<h2>Examples</h2> -<p> -Under the <span class="code">pexpect-VERSION</span> directory you should find -the <span class="code">examples</span> directory. -This is the best way to learn to use Pexpect. -See the descriptions of <a href="examples.html">Pexpect Examples</a>. -</p> -<h2><a name="doc"></a>API Documentation</h2> -<p> -<blockquote> -<a href="pexpect.html">pexpect</a> This is the main module that you want.<br> -<a href="pxssh.html">pxssh</a> Pexpect SSH is an extension of 'pexpect.spawn' that specializes in SSH.<br> -</blockquote> -the following are experimental extensions to Pexpect<br> -<blockquote> -<a href="fdpexpect.html">fdpexpect</a> fdpexpect extension of 'pexpect.spawn' that uses an open file descriptor.<br> -<a href="screen.html">SCREEN</a> This represents a virtual 'screen'.<br> -<a href="ANSI.html">ANSI</a> This parses ANSI/VT-100 terminal escape codes.<br> -<a href="FSM.html">FSM</a> This is a finite state machine used by ANSI.<br> -</blockquote> -</p> -<hr noshade="noshade" size="1"> -<h1><a name="status"></a>Project Status</h1> -<p>Automated pyunit tests reach over 80% -code coverage on pexpect.py. I regularly test on Linux and BSD -platforms. I try to test on Solaris and Irix. -</p> -<hr noshade="noshade" size="1"> -<h1><a name="requirements"></a>Requirements for use of Pexpect</h1> -<h2>Python</h2> -<blockquote> - <p>Pexpect was written and tested with Python 2.4. It should work on -earlier versions that have the <span class="code">pty</span> module. I -sometimes even manually test it with Python 1.5.2, but I can't easily -run the PyUnit test framework against Python 1.5.2, so I have less -confidence in Pexpect on Python 1.5.2.</p> -</blockquote> -<h2>pty module</h2> -<blockquote> - <p>Any POSIX system (UNIX) with a working <span class="code">pty</span> -module should be able to run Pexpect. The <span class="code">pty</span> -module is part of the Standard Python Library, so if you are running on -a POSIX system you should have it. The <span class="code">pty</span> -module does not run the same on all platforms. It should be solid on Linux -and BSD systems. I have taken effort to try to smooth the wrinkles out of the different platforms. To learn more -about the wrinkles see <a href="#bugs">Bugs</a> and <a href="#testing">Testing</a>.</p> -</blockquote> -<p>Pexpect does not currently work on the standard Windows Python (see -the pty requirement); however, it seems to work fine using <a - href="http://www.cygwin.com/">Cygwin</a>. It is possible to build -something like a pty for Windows, but it would have to use a different -technique that I am still investigating. I know it's possible because -Libes' Expect was ported to Windows. <i>If you have any ideas or -skills to contribute in this area then I would really appreciate some -tips on how to approach this problem.</i> </p> -<hr noshade="noshade" size="1"> -<h1><a name="overview"></a>Overview</h1> -<p>Pexpect can be used for automating interactive applications such as -ssh, ftp, mencoder, passwd, etc. The Pexpect interface was designed to be -easy to use. Here is an example of Pexpect in action:</p> -<blockquote> - <pre class="code"># This connects to the openbsd ftp site and<br># downloads the recursive directory listing.<br>import pexpect<br>child = pexpect.spawn ('ftp ftp.openbsd.org')<br>child.expect ('Name .*: ')<br>child.sendline ('anonymous')<br>child.expect ('Password:')<br>child.sendline ('noah@example.com')<br>child.expect ('ftp> ')<br>child.sendline ('cd pub')<br>child.expect('ftp> ')<br>child.sendline ('get ls-lR.gz')<br>child.expect('ftp> ')<br>child.sendline ('bye')<br></pre> -</blockquote> -<p> Obviously you could write an ftp client using Python's own <span - class="code">ftplib</span> module, but this is just a demonstration. -You can use this technique with any application. This is especially -handy if you are writing automated test tools.</p> - -<p>There are two important methods in Pexpect -- <span class="code"><b>expect()</b></span> -and <span class="code"><b>send()</b></span> (or <span class="code">sendline()</span> -which is like <span class="code">send()</span> with a linefeed). -The <span class="code">expect()</span> method waits for the child application -to return a given string. The string you specify is a regular expression, so -you can match complicated patterns. The <span class="code"><b>send()</b></span> method -writes a string to the child application. From the child's point of -view it looks just like someone typed the text from a terminal. After -each call to <span class="code"><b>expect()</b></span> the <span - class="code"><b>before</b></span> and <span class="code"><b>after</b></span> -properties will be set to the text printed by child application. The <span - class="code"><b>before</b></span> property will contain all text up to -the expected string pattern. The <span class="code"><b>after</b></span> string -will contain the text that was matched by the expected pattern. -The <span class="code">match</span> property is set to the <span class="code">re MatchObject</span>. -</p> - -<p>An example of Pexpect in action may make things more clear. This example uses -<span class="code">ftp</span> to login to the OpenBSD site; list files -in a directory; and then pass interactive control of the ftp session to -the human user.</p> -<blockquote> - <pre class="code">import pexpect<br>child = pexpect.spawn ('ftp ftp.openbsd.org')<br>child.expect ('Name .*: ')<br>child.sendline ('anonymous')<br>child.expect ('Password:')<br>child.sendline ('noah@example.com')<br>child.expect ('ftp> ')<br>child.sendline ('ls /pub/OpenBSD/')<br>child.expect ('ftp> ')<br>print child.before # Print the result of the ls command.<br>child.interact() # Give control of the child to the user.<br></pre> -</blockquote> -<h2>Special EOF and TIMEOUT patterns</h2> -<p> -There are two special patterns to match the End Of File or a Timeout condition. -You you can pass these patterns to <span class="code">expect()</span>. -These patterns are not regular expressions. Use them like predefined constants. -</p> -<p>If the child has died and you have read all the child's output then ordinarily -<span class="code">expect()</span> will raise an <span class="code">EOF</span> -exception. You can read everything up to the EOF without generating an -exception by using the EOF pattern <span class="code">expect(pexpect.EOF)</span>. -In this case everything the child has output will be available in the <span - class="code">before</span> property.</p> -<p>The pattern given to <span class="code">expect()</span> may be a -regular expression or it may also be a <b>list</b> of regular expressions. -This allows you to match multiple optional responses. The <span class="code">expect()</span> -method returns the index of the pattern that was matched. For example, -say you wanted to login to a server. After entering a password you -could get various responses from the server -- your password could be -rejected; or you could be allowed in and asked for your terminal type; -or you could be let right in and given a command prompt. The following -code fragment gives an example of this:</p> -<blockquote> - <pre class="code">child.expect('password:')<br>child.sendline (my_secret_password)<br># We expect any of these three patterns...<br>i = child.expect (['Permission denied', 'Terminal type', '[#\$] '])<br>if i==0:<br> print 'Permission denied on host. Can't login'<br> child.kill(0)<br>elif i==2:<br> print 'Login OK... need to send terminal type.'<br> child.sendline('vt100')<br> child.expect ('[#\$] ')<br>elif i==3:<br> print 'Login OK.'<br> print 'Shell command prompt', child.after</pre> -</blockquote> -<p>If nothing matches an expected pattern then expect will eventually -raise a TIMEOUT exception. The default time is 30 seconds, but you can -change this by passing a timeout argument to expect():</p> -<blockquote> - <pre class="code"># Wait no more than 2 minutes (120 seconds) for password prompt.<br>child.expect('password:', timeout=120)</pre> -</blockquote> -<h2>Find the end of line -- CR/LF conventions<br> -Matching at the end of a line can be tricky<br> -$ regex pattern is useless.<br> -</h2> -<p>Pexpect matches regular expressions a little differently than what -you might be used to. -</p> -<p><i><b>The $ pattern for end of line match is useless</b></i>. -The $ matches the end of string, but Pexpect reads from the child -one character at a time, so each character looks like the end of a line. -Pexpect can't do a look-ahead into the child's output stream. -In general you would have this situation when using regular expressions -with any stream.<br> -<i>Note, pexpect does have an internal buffer, so reads are faster -than one character at a time, but from the user's perspective the regex -patterns test happens one character at a time.</i></p> -<p>The best way to match the end of a line is to look for the -newline: "\r\n" (CR/LF). Yes, that does appear to be DOS-style. -It may surprise some UNIX people to learn that terminal TTY device drivers -(dumb, vt100, ANSI, xterm, etc.) all use the CR/LF combination to signify -the end of line. Pexpect uses a Pseudo-TTY device to talk to the child application, so -when the child app prints "\n" you actually see "\r\n". -</p> -<p><b>UNIX uses just linefeeds to end lines of text, but not when it -comes to TTY devices!</b> TTY devices are more like the Windows world. -Each line of text end with a CR/LF combination. When you intercept data -from a UNIX command from a TTY device you will find that the TTY device -outputs a CR/LF combination. A UNIX command may only write a linefeed -(\n), but the TTY device driver converts it to CR/LF. This means that -your terminal will see lines end with CR/LF (hex <span class="code">0D 0A</span>). -Since Pexpect emulates a terminal, to match ends of lines you have to -expect the CR/LF combination.</p> -<blockquote> - <p class="code">child.expect ('\r\n')</p> -</blockquote> -<p>If you just need to skip past a new line then <span class="code">expect -('\n')</span> by itself will work, but if you are expecting a specific -pattern before the end of line then you need to explicitly look for the -\r. For example the following expects a word at the end of a line:</p> -<blockquote> - <p class="code">child.expect ('\w+\r\n')</p> -</blockquote> -<p>But the following would both fail:</p> -<blockquote> - <p class="code">child.expect ('\w+\n')</p> -</blockquote> -<p>And as explained before, trying to use '$' to match the end of line -would not work either:</p> -<blockquote> - <p class="code">child.expect ('\w+$')</p> -</blockquote> -<p>So if you need to explicitly look for the END OF LINE, you want to -look for the CR/LF combination -- not just the LF and not the $ pattern.</p> -<p>This problem is not limited to Pexpect. This problem happens any -time you try to perform a regular expression match on a stream. Regular -expressions need to look ahead. With a stream it is hard to look ahead -because the process generating the stream may not be finished. There is no -way to know if the process has paused momentarily or is finished and -waiting for you. <font color="#cc0000">Pexpect must implicitly always -do a NON greedy match (minimal) at the end of a input {### already said -this}.</font> </p> -<p>Pexpect compiles all regular expressions with the DOTALL flag. With -the DOTALL flag a "." will match a newline. See the Python <a - href="http://www.python.org/doc/current/lib/node115.html#l2h-733">documentation</a></p> -<h2>Beware of + and * at the end of input.</h2> -<p>Remember that any time you try to match a pattern that needs -look-ahead that you will always get a minimal match (non greedy). For -example, the following will always return just one character:</p> -<blockquote> - <p class="code">child.expect ('.+')</p> -</blockquote> -<p>This example will match successfully, but will always return no -characters:</p> -<blockquote> - <p class="code">child.expect ('.*')</p> -</blockquote> -<p>Generally any star * expression will match as little as possible</p> -<p>One thing you can do is to try to force a non-ambiguous character at -the end of your <span class="code">\d+</span> pattern. Expect that -character to delimit the string. For example, you might try making the -end of your pattrn be <span class="code">\D+</span> instead of <span - class="code">\D*</span>. That means number digits alone would not -satisfy the (<span class="code">\d+</span>) pattern. You would need -some number(s) and at least one <span class="code">\D</span> at the -end. </p> -<h2>Matching groups</h2> -<p>You can group regular expression using parenthesis. After a match, -the <span class="code">match</span> parameter of the spawn object will -contain the Python Match object. </p> -<h2>Examples</h2> -<p>Using "match" and groups...</p> -<h2>Debugging</h2> -<p>If you get the string value of a pexpect.spawn object you will get -lots of useful debugging information. For debugging it's very useful to -use the following pattern:</p> -<p>try:<br> - i = child.expect ([pattern1, pattern2, pattern3, -etc])<br> -except:<br> - print "Exception was thrown"<br> - print "debug information:"<br> - print str(child)<br> -</p> -<p>It is also useful to log the child's input and out to a file or the -screen. The following will turn on logging and send output to stdout -(the screen).<br> -</p> -<p> child = pexpect.spawn (foo)<br> - child.logfile = sys.stdout<br> -<br> -</p> -<hr noshade="noshade" size="1"> -<h1>Exceptions</h1> -<p><b>EOF</b></p> -<p>Note that two flavors of EOF Exception may be thrown. They are -virtually identical except for the message string. For practical -purposes you should have no need to distinguish between them, but they -do give a little extra information about what type of platform you are -running. The two messages are:</p> -<blockquote> - <p class="code">End Of File (EOF) in read(). Exception style platform.</p> - <p class="code">End Of File (EOF) in read(). Empty string style -platform.</p> -</blockquote> -<p>Some UNIX platforms will throw an exception when you try to read -from a file descriptor in the EOF state. Other UNIX platforms instead -quietly return an empty string to indicate that the EOF state has been -reached.</p> -<p><b>Expecting EOF</b></p> -<p>If you wish to read up to the end of the child's output without -generating an <span class="code">EOF</span> exception then use the <span - class="code">expect(pexpect.EOF)</span> method.</p> -<p><b>TIMEOUT</b></p> -<p>The <span class="code">expect()</span> and <span class="code">read()</span> -methods will also timeout if the child does not generate any output for -a given amount of time. If this happens they will raise a <span - class="code">TIMEOUT</span> exception. You can have these method -ignore a timeout and block indefinitely by passing None for the timeout -parameter.</p> -<blockquote> - <p class="code">child.expect(pexpect.EOF, timeout=None)</p> -</blockquote> -<hr noshade="noshade" size="1"> -<h1><a name="faq"></a>FAQ</h1> -<p><b>Q: Why don't shell pipe and redirect (| and >) work when I -spawn a command?</b></p> -<p> - -A: Remember that Pexpect does NOT interpret shell meta characters such as -redirect, pipe, or wild cards (>, |, or *). That's done by a shell not the -command you are spawning. This is a common mistake. If you want to run a -command and pipe it through another command then you must also start a shell. -For example: - -<pre> - child = pexpect.spawn('/bin/bash -c "ls -l | grep LOG > log_list.txt"') - child.expect(pexpect.EOF) -</pre> - -The second form of spawn (where you pass a list of arguments) is useful in -situations where you wish to spawn a command and pass it its own argument list. -This can make syntax more clear. For example, the following is equivalent to -the previous example: - -<pre> - shell_cmd = 'ls -l | grep LOG > log_list.txt' - child = pexpect.spawn ('/bin/bash', ['-c', shell_cmd]) - child.expect (pexpect.EOF) -</pre> - -</p> -<p><b>Q: Isn't there already a Python Expect?</b></p> -<p>A: Yes, there are several of them. They usually require you to -compile C. I wanted something that was pure Python and preferably a -single module that was simple to install. I also wanted something that -was easy to use. This pure Python expect only recently became possible -with the introduction of the pty module in the standard Python library. -Previously C extensions were required.</p> - -<p><strong>Q: The before and after properties sound weird.</strong></p> -<p>Originally I was going to model Pexpect more after Expect, but then -I found that I could never remember how to get the context of the stuff -I was trying to parse. I hate having to read my own documentation. I -decided that it was easier for me to remember what before and after -was. It just so happens that this is how the -B and -A options in grep -works, so that made it even easier for me to remember. Whatever makes -my life easier is what's best.</p> - -<p><b>Q: Why not just use Expect?</b></p> -<p>A: I love it. It's great. I has bailed me out of some real jams, but -I wanted something that would do 90% of what I need from Expect; be 10% -of the size; and allow me to write my code in Python instead of TCL. -Pexpect is not nearly as big as Expect, but Pexpect does everything I -have ever used Expect for. -<!-- :-P If I liked TCL then you wouldn't be reading this. My appologies to Don Libes -- Expect is cool, TK is cool, but TCL is only slightly better than Perl in my book. Hopefully after Expyct is done I will not need to use Expect anymore -- except for that lovely autoexpect tool. Damn, I wish I had that! --> </p> - -<p><b>Q: Why not just use a pipe (popen())?</b></p> -<p>A: A pipe works fine for getting the output to non-interactive -programs. If you just want to get the output from <span class="code">ls</span>, -<span class="code">uname</span>, or <span class="code">ping</span> -then this works. Pipes do not work very well for interactive programs -and pipes will almost certainly fail for most applications that ask for -passwords such as telnet, ftp, or ssh.</p> -<p>There are two reasons for this. </p> -<p>First an application may bypass stdout and print directly to its -controlling TTY. Something like SSH will do this when it asks you for a -password. This is why you cannot redirect the password prompt because -it does not go through stdout or stderr.</p> -<p>The second reason is because most applications are built using the C -Standard IO Library (anything that uses <span class="code">#include -<stdio.h></span>). One of the features of the stdio library is -that it buffers all input and output. Normally output is <b><i>line -buffered</i></b> when a program is printing to a TTY (your terminal -screen). Every time the program prints a line-feed the currently -buffered data will get printed to your screen. The problem comes when -you connect a pipe. The stdio library is smart and can tell that it is -printing to a pipe instead of a TTY. In that case it switches from line -buffer mode to <i><b>block buffered</b></i>. In this mode the -currently buffered data is flushed when the buffer is full. This causes -most interactive programs to deadlock. Block buffering is more -efficient when writing to disks and pipes. Take the situation where a -program prints a message "Enter your user name:\n" and then waits for -you type type something. In block buffered mode, the stdio library will -not put the message into the pipe even though a linefeed is printed. -The result is that you never receive the message, yet the child -application will sit and wait for you to type a response. Don't confuse -the stdio lib's buffer with the pipe's buffer. The pipe buffer is -another area that can cause problems. You could flush the input side of -a pipe, whereas you have no control over the stdio library buffer. </p> -<p>More information: the Standard IO library has three states for a -FILE *. These are: _IOFBF for block buffered; _IOLBF for line buffered; -and _IONBF for unbuffered. The STDIO lib will use block buffering when -talking to a block file descriptor such as a pipe. This is usually not -helpful for interactive programs. Short of recompiling your program to -include fflush() everywhere or recompiling a custom stdio library there -is not much a controlling application can do about this if talking over -a pipe.</p> -<p> The program may have put data in its output that remains unflushed -because the output buffer is not full; then the program will go and -deadlock while waiting for input -- because you never send it any -because you are still waiting for its output (still stuck in the -STDIO's output buffer).</p> -<p>The answer is to use a pseudo-tty. A TTY device will force <i><b>line</b></i> -buffering (as opposed to block buffering). Line buffering means that -you will get each line when the child program sends a line feed. This -corresponds to the way most interactive programs operate -- send a line -of output then wait for a line of input.</p> -<p>I put "answer" in quotes because it's ugly solution and because -there is no POSIX standard for pseudo-TTY devices (even though they -have a TTY standard...). What would make more sense to me would be to -have some way to set a mode on a file descriptor so that it will tell -the STDIO to be line-buffered. I have investigated, and I don't think -there is a way to set the buffered state of a child process. The STDIO -Library does not maintain any external state in the kernel or whatnot, -so I don't think there is any way for you to alter it. I'm not quite -sure how this line-buffered/block-buffered state change happens -internally in the STDIO library. I think the STDIO lib looks at the -file descriptor and decides to change behavior based on whether it's a -TTY or a block file (see isatty()).</p> -<p>I hope that this qualifies as helpful.</p> - -<h1>Don't use a pipe to control another application...</h1> -<p>Pexpect may seem similar to <span class="code">os.popen()</span> or -<span class="code">commands</span> module. The main difference is that -Pexpect (like Expect) uses a pseudo-TTY to talk to the child -application. Most applications do no work well through the system() -call or through pipes. And probably all applications that ask a user to -type in a password will fail. These applications bypass the stdin and -read directly from the TTY device. Many applications do not explicitly -flush their output buffers. This causes deadlocks if you try to control -an interactive application using a pipe. What happens is that most UNIX -applications use the stdio (#include <stdio.h>) for input and -output. The stdio library behaves differently depending on where the -output is going. There is no way to control this behavior from the -client end.<br> -</p> - -<p><b>Q: Can I do screen scraping with this thing?</b></p> -<p>A: That depends. If your application just does line-oriented output -then this is easy. If it does screen-oriented output then it may work, -but it could be hard. For example, trying to scrape data from the 'top' -command would be hard. The top command repaints the text window. </p> -<p>I am working on an ANSI / VT100 terminal emulator that will have -methods to get characters from an arbitrary X,Y coordinate of the -virtual screen. It works and you can play with it, but I have no -working examples at this time.</p> -<hr noshade="noshade" size="1"> -<h1><a name="bugs"></a>Bugs</h1> -<h2>Threads</h2> -<p>On Linux (RH 8) you cannot spawn a child from a different thread and -pass the handle back to a worker thread. The child is successfully -spawned but you can't interact with it. The only way to make it work is -to spawn and interact with the child all in the same thread. [Adam -Kerrison] </p> -<h2><a name="echo_bug"></a>Timing issue with send() and sendline()</h2> -<p>This problem has been addressed and should not effect most users.</p> -<p>It is sometimes possible to read an echo of the string sent with <span - class="code">send()</span> and <span class="code">sendline()</span>. -If you call <span class="code">sendline()</span> and then immediately -call <span class="code">readline()</span> you may get part of your -output echoed back. You may read back what you just wrote even if the -child application does not explicitly echo it. Timing is critical. This -could be a security issue when talking to an application that asks for -a password; otherwise, this does not seem like a big deal. <i>But why -do TTYs do this</i>?</p> -<p>People usually report this when they are trying to control SSH or -some other login. For example, if your code looks something like this: </p> -<pre class="code">child.expect ('[pP]assword:')<br>child.sendline (my_password)</pre> -<p><br> -<blockquote> -1. SSH prints "password:" prompt to the user.<br> -2. SSH turns off echo on the TTY device.<br> -3. SSH waits for user to enter a password.<br> -</blockquote> -When scripting with Pexpect what can happen is that Pexpect will response to the "password:" prompt -before SSH has had time to turn off TTY echo. In other words, Pexpect sends the password between -steps 1. and 2., so the password gets echoed back to the TTY. I would call this an SSH bug. -</p> -<p> -Pexpect now automatically adds a short delay before sending data to a child process. -This more closely mimics what happens in the usual human-to-app interaction. -The delay can be tuned with the 'delaybeforesend' attribute of the spawn class. -In general, this fixes the problem for everyone and so this should not be an issue -for most users. For some applications you might with to turn it off. - child = pexpect.spawn ("ssh user@example.com") - child.delaybeforesend = 0 -</p> -<p><br> -</p> -<p>Try changing it to look like the following. I know that this fix -does not look correct, but it works. I have not figured out exactly -what is happening. You would think that the sleep should be after the -sendline(). The fact that the sleep helps when it's between the -expect() and the sendline() must be a clue.</p> -<pre class="code">child.expect ('[pP]assword:')<br>child.sendline (my_password)</pre> -<h2>Timing issue with isalive()</h2> -<p>Reading the state of isalive() immediately after a child exits may -sometimes return 1. This is a race condition. The child has closed its -file descriptor, but has not yet fully exited before Pexpect's -isalive() executes. Addings a slight delay before the isalive() will -help. In the following example <span class="code">isalive()</span> -sometimes returns 1:</p> -<blockquote> - <pre class="code">child = pexpect.spawn('ls')<br>child.expect(pexpect.EOF)<br>print child.isalive()</pre> -</blockquote> -<p>But if there is any delay before the call to <span class="code">isalive()</span> -then it will always return 0 as expected.</p> -<blockquote> - <pre class="code">child = pexpect.spawn('ls')<br>child.expect(pexpect.EOF)<br>time.sleep(0.1)<br>print child.isalive()</pre> -</blockquote> - -<h2>Truncated output just before child exits</h2> -<p><i>So far I have seen this only on older versions of <b>Apple's MacOS X</b>.</i> -If the child application quits it may not flush its output buffer. This -means that your Pexpect application will receive an EOF even though it -should have received a little more data before the child died. This is -not generally a problem when talking to interactive child applications. -One example where it is a problem is when trying to read output from a -program like '<span class="code">ls</span>'. You may receive most of -the directory listing, but the last few lines will get lost before you -receive an EOF. The reason for this is that '<span class="code">ls</span>' -runs; completes its task; and then exits. The buffer is not flushed -before exit so the last few lines are lost. The following example -demonstrates the problem:</p> -<p> </p> -<blockquote> - <pre class="code">child = pexpect.spawn ('ls -l')<br>child.expect (pexpect.EOF)<br>print child.before <br> </pre> -</blockquote> -<p></p> - -<h2>Controlling SSH on Solaris</h2> -<p>Pexpect does not yet work perfectly on Solaris. -One common problem is that SSH sometimes will not allow TTY password -authentication. For example, you may expect SSH to ask you for a -password using code like this: -</p> -<pre class="code">child = pexpect.spawn ('ssh user@example.com')<br>child.expect ('assword')<br>child.sendline ('mypassword')<br></pre> -You may see the following error come back from a spawned -child SSH: -<p></p> -<blockquote>Permission denied (publickey,keyboard-interactive). </blockquote> -<p> -This means that SSH thinks it can't access the TTY to ask you for your -password. -The only solution I have found is to use public key authentication with -SSH. -This bypasses the need for a password. I'm not happy with this -solution. -The problem is due to poor support for Solaris Pseudo TTYs in the -Python -Standard Library. </p> -<hr noshade="noshade" size="1"> -<h1><a name="changes"></a>CHANGES</h1> -<h2>Current Release</h2> -<p>Fixed OSError exception when a pexpect object is cleaned up. -Previously you might have seen this exception:</p> -<blockquote> - <pre class="code">Exception exceptions.OSError: (10, 'No child processes') <br>in <bound method spawn.__del__ of<br><pexpect.spawn instance at 0xd248c>> ignored</pre> -</blockquote> -<p>You should not see that anymore. Thanks to Michael Surette.</p> -<p>Added support for buffering reads. This greatly improves speed when -trying to match long output from a child process. When you create an -instance of the spawn object you can then set a buffer size. For now -you MUST do the following to turn on buffering -- it may be on by -default in future version.</p> -<blockquote> - <pre class="code">child = pexpect.spawn ('my_command')<br>child.maxread=1000 # Sets buffer to 1000 characters.</pre> -</blockquote> -<div> -<p>I made a subtle change to the way TIMEOUT and EOF exceptions behave. -Previously you could either expect these states in which case pexpect -will not raise an exception, or you could just let pexpect raise an -exception when these states were encountered. If you expected the -states then the 'before' property was set to everything before the -state was encountered, but if you let pexpect raise the exception then -'before' was not set. Now the 'before' property will get set either way -you choose to handle these states.</p> -<h2><i>Older changes...</i></h2> -<p>The spawn object now provides iterators for a <i>file-like interface</i>. -This makes Pexpect a more complete file-like object. You can now write -code like this:</p> -<blockquote> - <pre class="code">child = pexpect.spawn ('ls -l')<br>for line in child:<br> print line<br></pre> -</blockquote> -<p>I added the attribute <span class="code">exitstatus</span>. This -will give the exit code returned by the child process. This will be set -to <span class="code">None</span> while the child is still alive. When -<span class="code">isalive()</span> returns 0 then <span class="code">exitstatus</span> -will be set.</p> -<p>I made a few more tweaks to <span class="code">isalive()</span> so -that it will operate more consistently on different platforms. Solaris -is the most difficult to support.</p> -<p> </p> -<p>You can now put <span class="code">TIMEOUT</span> in a list of -expected patterns. This is just like putting <span class="code">EOF</span> -in the pattern list. Expecting for a <span class="code">TIMEOUT</span> -may not be used as often as <span class="code">EOF</span>, but this -makes Pexpect more consitent.</p> -<p>Thanks to a suggestion and sample code from Chad J. Schroeder I -added the ability for Pexpect to operate on a file descriptor that is -already open. This means that Pexpect can be used to control streams -such as those from serial port devices. Now you just pass the integer -file descriptor as the "command" when contsructing a spawn open. For -example on a Linux box with a modem on ttyS1:</p> -<blockquote> - <pre class="code">fd = os.open("/dev/ttyS1", os.O_RDWR|os.O_NONBLOCK|os.O_NOCTTY)<br>m = pexpect.spawn(fd) # Note integer fd is used instead of usual string.<br>m.send("+++") # Escape sequence<br>m.send("ATZ0\r") # Reset modem to profile 0<br>rval = m.expect(["OK", "ERROR"])</pre> -</blockquote> -<h3>Pexpect now tests itself on Compile Farm!</h3> -<p>I wrote a nice script that uses ssh to connect to each machine on -Source Forge's Compile Farm and then run the testall.py script for each -platform. The result of the test is then recorded for each platform. -Now it's easy to run regression tests across multiple platforms.</p> -<h3>Pexpect is a file-like object</h3> -<p>The spawn object now provides a <i>file-like interface</i>. It -supports most of the methods and attributes defined for Python File -Objects. </p> -<p>I changed write and writelines() so that they no longer return a -value. Use send() if you need that functionality. I did this to make -the Spawn object more closely match a file-like object.</p> -<p>read() was renamed to read_nonblocking(). I added a new read() -method that matches file-like object interface. In general, you should -not notice the difference except that read() no longer allows you to -directly set the timeout value. I hope this will not effect any -existing code. Switching to read_nonblocking() should fix existing code.</p> -<p>I changed the name of <span class="code">set_echo()</span> to <span - class="code">setecho()</span>.</p> -<p>I changed the name of <span class="code">send_eof()</span> to <span - class="code">sendeof()</span>.</p> -<p>I modified <span class="code">kill()</span> so that it checks to -make sure the pid isalive().</p> -<p>I modified <span class="code">spawn()</span> (really called from <span - class="code">__spawn()</span>)so that it does not raise an expection -if <span class="code">setwinsize()</span> fails. Some platforms such -as Cygwin do not like setwinsize. This was a constant problem and since -it is not a critical feature I decided to just silence the error. -Normally I don't like to do that, but in this case I'm making an -exception.</p> -<p>Added a method <span class="code">close()</span> that does what you -think. It closes the file descriptor of the child application. It makes -no attempt to actually kill the child or wait for its status. </p> -<p>Add variables <span class="code">__version__</span> and <span - class="code">__revision__</span> (from cvs) to the pexpect modules. -This is mainly helpful to me so that I can make sure that I'm testing -with the right version instead of one already installed.</p> -<h3>Logging changes</h3> -<blockquote> - <p><span class="code">log_open()</span> and <span class="code">log_close()</span> -have been removed. Now use <span class="code">setlog()</span>. The <span - class="code">setlog()</span> method takes a file object. This is far -more flexible than the previous log method. Each time data is written -to the file object it will be flushed. To turn logging off simply call <span - class="code">setlog()</span> with None.</p> -</blockquote> -<h2>isalive changes</h2> -<blockquote> - <p>I renamed the <span class="code">isAlive()</span> method to <span - class="code">isalive()</span> to match the more typical naming style -in Python. Also the technique used to detect child process status has -been drastically modified. Previously I did some funky stuff with -signals which caused indigestion in other Python modules on some -platforms. It's was a big headache. It still is, but I think it works -better now.</p> -</blockquote> -<h3>attribute name changes</h3> -<blockquote> - <p>The names of some attributes have been changed. This effects the -names of the attributes that are set after called the <span - class="code">expect()</span> method.</p> - <table class="pymenu" border="0" cellpadding="5"> - <tbody> - <tr> - <th class="pymenu">NEW NAME</th> - <th class="pymenu">OLD NAME</th> - </tr> - <tr> - <td><span class="code">before</span><br> - <i>Everything before the match.</i></td> - <td><span class="code">before</span></td> - </tr> - <tr> - <td><span class="code">after</span><br> - <i>Everything after and including the first character of the -match</i></td> - <td><span class="code">matched</span></td> - </tr> - <tr> - <td><span class="code">match</span><br> - <i>This is the re MatchObject from the match.<br> -You can get groups() from this.<br> -See '<span class="code">uptime.py</span>' in the examples tar ball.</i></td> - <td><i>New -- Did not exist</i></td> - </tr> - </tbody> - </table> -</blockquote> -<h3>EOF changes</h3> -<blockquote> - <p>The <span class="code">expect_eof()</span> method is gone. You -can now simply use the <span class="code">expect()</span> method to -look for EOF.</p> - <p>Was:</p> - <blockquote> - <p><span class="code">p.expect_eof ()</span></p> - </blockquote> - <p>Now:</p> - <blockquote> - <p><span class="code">p.expect (pexpect.EOF)</span></p> - </blockquote> -</blockquote> -<hr noshade="noshade" size="1"> -<h1><a name="testing"></a>TESTING</h1> -<p>The following platforms have been tested:</p> -<!-- -<table class="pymenu" border="0" cellpadding="5"> - <tbody> - <tr> - <th class="pymenu">PLATFORM</th> - <th class="pymenu">RESULTS</th> - </tr> - <tr> - <td>Linux 2.4.9-ac10-rmk2-np1-cerf2<br> -armv4l</td> - <td><b><i>all tests passed</i></b></td> - </tr> - <tr> - <td>Linux 2.4.18 #2<br> -sparc64</td> - <td><b><i>all tests passed</i></b></td> - </tr> - <tr> - <td>MacOS X Darwin Kernel Version 5.5<br> -powerpc</td> - <td> - <p>failed more than one test.</p> - <p>Generally Pexpect works on OS X, but the nature of the quirks -cause a many of the tests to fail. See <a href="#bugs">bugs</a> -(Incomplete Child Output). The problem is more than minor, but Pexpect -is still more than useful for most tasks. The problem is an edge case.</p> - </td> - </tr> - <tr> - <td>Linux 2.2.20<br> -alpha<br> - </td> - <td><b><i>all tests passed</i></b></td> - </tr> - <tr> - <td>Linux 2.4.18-5smp<br> -i686</td> - <td><b><i>all tests passed</i></b></td> - </tr> - <tr> - <td>OpenBSD 2.9 GENERIC#653<br> -i386</td> - <td><b><i>all tests passed</i></b></td> - </tr> - <tr> - <td>Solaris</td> - <td> - <p>failed <span class="code">test_destructor</span></p> - <p>Otherwise, this is working pretty well. The destructor problem -is minor. For some reason, the <i>second</i> time a pty file -descriptor is created and deleted it never gets returned for use. It -does not effect the first time or the third time or any time after -that. It's only the second time. This is weird... This could be a file -descriptor leak, or it could be some peculiarity of how Solaris -recycles them. I thought it was a UNIX requirement for the OS to give -you the lowest available filedescriptor number. In any case, this -should not be a problem unless you create hundreds of pexpect -instances... It may also be a pty module bug. </p> - </td> - </tr> - <tr> - <td>Windows XP Cygwin</td> - <td>failed <span class="code">test_destructor</span>. That it -works at all is amazing to me. Cygwin rules!</td> - </tr> - </tbody> -</table> ---> -<h1> </h1> -<h1><a name="todo">TO DO</a></h1> -<p>Add an option to add a delay after each expect() or before each -read()/readline() call to automatically avoid the <a href="#echo_bug">echo -bug</a>.</p> -<p> </p> -</div> -<hr noshade="noshade" size="1"> -<table border="0"> - <tbody> - <tr> - <td> <a href="http://www.noah.org/email/"><img src="email.png" - alt="Click to send email." border="0" height="16" width="100"></a> </td> - </tr> - </tbody> -</table> -</div> -<div id="Menu"><b>INDEX</b><br> -<hr noshade="noshade" size="1"> <a href="#license" - title="Python Software Foundation License">License</a><br> -<a href="#download" title="Download and setup instructions">Download</a><br> -<a href="#doc" title="Documentation and overview">Documentation</a><br> -<a href="#status" title="Project Status">Project Status</a><br> -<a href="#requirements" title="System requirements to use Pexpect">Requirements</a><br> -<a href="#overview" title="Overview of what Pexpect does">Overview</a><br> -<a href="#faq" title="FAQ">FAQ</a><br> -<a href="#bugs" title="Bugs and work-arounds">Known Bugs</a><br> -<a href="#changes" title="What's new with Pexpect">Recent Changes</a><br> -<a href="#testing" title="Test results on various platforms">Testing</a><br> -<a href="#todo" title="What to do next">To do</a><br> -<a href="http://pexpect.svn.sourceforge.net/viewvc/pexpect/trunk/pexpect/" title="browse SVN">Browse SVN</a><br> -<br> -<a href="http://sourceforge.net/projects/pexpect/" - title="The Pexpect project page on SourceForge.net"> <img - src="http://sourceforge.net/sflogo.php?group_id=59762&type=5" - alt="The Pexpect project page on SourceForge.net" border="0" - height="31" width="105"> </a> </div> -</body> -</html> diff --git a/pexpect/examples/README b/pexpect/examples/README deleted file mode 100644 index be21e96..0000000 --- a/pexpect/examples/README +++ /dev/null @@ -1,89 +0,0 @@ -This directory contains scripts that give examples of using Pexpect. - -hive.py - This script creates SSH connections to a list of hosts that - you provide. Then you are given a command line prompt. Each - shell command that you enter is sent to all the hosts. The - response from each host is collected and printed. For example, - you could connect to a dozen different machines and reboot - them all at once. - -script.py - This implements a command similar to the classic BSD "script" command. - This will start a subshell and log all input and output to a file. - This demonstrates the interact() method of Pexpect. - -fix_cvs_files.py - This is for cleaning up binary files improperly added to - CVS. This script scans the given path to find binary files; - checks with CVS to see if the sticky options are set to -kb; - finally if sticky options are not -kb then uses 'cvs admin' - to set the -kb option. - -ftp.py - This demonstrates an FTP "bookmark". - This connects to an ftp site; does a few ftp commands; and then gives the user - interactive control over the session. In this case the "bookmark" is to a - directory on the OpenBSD ftp server. It puts you in the i386 packages - directory. You can easily modify this for other sites. - This demonstrates the interact() method of Pexpect. - -monitor.py - This runs a sequence of system status commands on a remote host using SSH. - It runs a simple system checks such as uptime and free to monitor - the state of the remote host. - -passmass.py - This will login to a list of hosts and change the password of the - given user. This demonstrates scripting logins; although, you could - more easily do this using the pxssh subclass of Pexpect. - See also the "hive.py" example script for a more general example - of scripting a collection of servers. - -python.py - This starts the python interpreter and prints the greeting message backwards. - It then gives the user interactive control of Python. It's pretty useless! - -rippy.py - This is a wizard for mencoder. It greatly simplifies the process of - ripping a DVD to mpeg4 format (XviD, DivX). It can transcode from any - video file to another. It has options for resampling the audio stream; - removing interlace artifacts, fitting to a target file size, etc. - There are lots of options, but the process is simple and easy to use. - -sshls.py - This lists a directory on a remote machine. - -ssh_tunnel.py - This starts an SSH tunnel to a remote machine. It monitors the connection - and restarts the tunnel if it goes down. - -uptime.py - This will run the uptime command and parse the output into python variables. - This demonstrates using a single regular expression to match the output - of a command and capturing different variable in match groups. - The regular expression takes into account a wide variety of different - formats for uptime output. - -df.py - This collects filesystem capacity info using the 'df' command. - Tuples of filesystem name and percentage are stored in a list. - A simple report is printed. Filesystems over 95% capacity are highlighted. - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - diff --git a/pexpect/examples/astat.py b/pexpect/examples/astat.py deleted file mode 100755 index daaffd0..0000000 --- a/pexpect/examples/astat.py +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env python - -'''This runs Apache Status on the remote host and returns the number of requests per second. - -./astat.py [-s server_hostname] [-u username] [-p password] - -s : hostname of the remote server to login to. - -u : username to user for login. - -p : Password to user for login. - -Example: - This will print information about the given host: - ./astat.py -s www.example.com -u mylogin -p mypassword - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import os, sys, time, re, getopt, getpass -import traceback -import pexpect, pxssh - -def exit_with_usage(): - - print globals()['__doc__'] - os._exit(1) - -def main(): - - ###################################################################### - ## Parse the options, arguments, get ready, etc. - ###################################################################### - try: - optlist, args = getopt.getopt(sys.argv[1:], 'h?s:u:p:', ['help','h','?']) - except Exception, e: - print str(e) - exit_with_usage() - options = dict(optlist) - if len(args) > 1: - exit_with_usage() - - if [elem for elem in options if elem in ['-h','--h','-?','--?','--help']]: - print "Help:" - exit_with_usage() - - if '-s' in options: - hostname = options['-s'] - else: - hostname = raw_input('hostname: ') - if '-u' in options: - username = options['-u'] - else: - username = raw_input('username: ') - if '-p' in options: - password = options['-p'] - else: - password = getpass.getpass('password: ') - - # - # Login via SSH - # - p = pxssh.pxssh() - p.login(hostname, username, password) - p.sendline('apachectl status') - p.expect('([0-9]+\.[0-9]+)\s*requests/sec') - requests_per_second = p.match.groups()[0] - p.logout() - print requests_per_second - -if __name__ == "__main__": - try: - main() - except Exception, e: - print str(e) - traceback.print_exc() - os._exit(1) - diff --git a/pexpect/examples/bd_client.py b/pexpect/examples/bd_client.py deleted file mode 100755 index 6bf7e71..0000000 --- a/pexpect/examples/bd_client.py +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env python - -'''This is a very simple client for the backdoor daemon. This is intended more -for testing rather than normal use. See bd_serv.py - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import socket -import sys, time, select - -def recv_wrapper(s): - r,w,e = select.select([s.fileno()],[],[], 2) - if not r: - return '' - #cols = int(s.recv(4)) - #rows = int(s.recv(4)) - cols = 80 - rows = 24 - packet_size = cols * rows * 2 # double it for good measure - return s.recv(packet_size) - -#HOST = '' #'localhost' # The remote host -#PORT = 1664 # The same port as used by the server -s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) -s.connect(sys.argv[1])#(HOST, PORT)) -time.sleep(1) -#s.setblocking(0) -#s.send('COMMAND' + '\x01' + sys.argv[1]) -s.send(':sendline ' + sys.argv[2]) -print recv_wrapper(s) -s.close() -sys.exit() -#while True: -# data = recv_wrapper(s) -# if data == '': -# break -# sys.stdout.write (data) -# sys.stdout.flush() -#s.close() - diff --git a/pexpect/examples/bd_serv.py b/pexpect/examples/bd_serv.py deleted file mode 100755 index 1681c2b..0000000 --- a/pexpect/examples/bd_serv.py +++ /dev/null @@ -1,334 +0,0 @@ -#!/usr/bin/env python - -'''Back door shell server - -This exposes an shell terminal on a socket. - - --hostname : sets the remote host name to open an ssh connection to. - --username : sets the user name to login with - --password : (optional) sets the password to login with - --port : set the local port for the server to listen on - --watch : show the virtual screen after each client request - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -# Having the password on the command line is not a good idea, but -# then this entire project is probably not the most security concious thing -# I've ever built. This should be considered an experimental tool -- at best. -import pxssh, pexpect, ANSI -import time, sys, os, getopt, getpass, traceback, threading, socket - -def exit_with_usage(exit_code=1): - - print globals()['__doc__'] - os._exit(exit_code) - -class roller (threading.Thread): - - '''This runs a function in a loop in a thread.''' - - def __init__(self, interval, function, args=[], kwargs={}): - - '''The interval parameter defines time between each call to the function. - ''' - - threading.Thread.__init__(self) - self.interval = interval - self.function = function - self.args = args - self.kwargs = kwargs - self.finished = threading.Event() - - def cancel(self): - - '''Stop the roller.''' - - self.finished.set() - - def run(self): - - while not self.finished.isSet(): - # self.finished.wait(self.interval) - self.function(*self.args, **self.kwargs) - -def endless_poll (child, prompt, screen, refresh_timeout=0.1): - - '''This keeps the screen updated with the output of the child. This runs in - a separate thread. See roller(). ''' - - #child.logfile_read = screen - try: - s = child.read_nonblocking(4000, 0.1) - screen.write(s) - except: - pass - #while True: - # #child.prompt (timeout=refresh_timeout) - # try: - # #child.read_nonblocking(1,timeout=refresh_timeout) - # child.read_nonblocking(4000, 0.1) - # except: - # pass - -def daemonize (stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'): - - '''This forks the current process into a daemon. Almost none of this is - necessary (or advisable) if your daemon is being started by inetd. In that - case, stdin, stdout and stderr are all set up for you to refer to the - network connection, and the fork()s and session manipulation should not be - done (to avoid confusing inetd). Only the chdir() and umask() steps remain - as useful. - - References: - UNIX Programming FAQ - 1.7 How do I get my program to act like a daemon? - http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC16 - - Advanced Programming in the Unix Environment - W. Richard Stevens, 1992, Addison-Wesley, ISBN 0-201-56317-7. - - The stdin, stdout, and stderr arguments are file names that will be opened - and be used to replace the standard file descriptors in sys.stdin, - sys.stdout, and sys.stderr. These arguments are optional and default to - /dev/null. Note that stderr is opened unbuffered, so if it shares a file - with stdout then interleaved output may not appear in the order that you - expect. ''' - - # Do first fork. - try: - pid = os.fork() - if pid > 0: - sys.exit(0) # Exit first parent. - except OSError, e: - sys.stderr.write ("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror) ) - sys.exit(1) - - # Decouple from parent environment. - os.chdir("/") - os.umask(0) - os.setsid() - - # Do second fork. - try: - pid = os.fork() - if pid > 0: - sys.exit(0) # Exit second parent. - except OSError, e: - sys.stderr.write ("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror) ) - sys.exit(1) - - # Now I am a daemon! - - # Redirect standard file descriptors. - si = open(stdin, 'r') - so = open(stdout, 'a+') - se = open(stderr, 'a+', 0) - os.dup2(si.fileno(), sys.stdin.fileno()) - os.dup2(so.fileno(), sys.stdout.fileno()) - os.dup2(se.fileno(), sys.stderr.fileno()) - - # I now return as the daemon - return 0 - -def add_cursor_blink (response, row, col): - - i = (row-1) * 80 + col - return response[:i]+'<img src="http://www.noah.org/cursor.gif">'+response[i:] - -def main (): - - try: - optlist, args = getopt.getopt(sys.argv[1:], 'h?d', ['help','h','?', 'hostname=', 'username=', 'password=', 'port=', 'watch']) - except Exception, e: - print str(e) - exit_with_usage() - - command_line_options = dict(optlist) - options = dict(optlist) - # There are a million ways to cry for help. These are but a few of them. - if [elem for elem in command_line_options if elem in ['-h','--h','-?','--?','--help']]: - exit_with_usage(0) - - hostname = "127.0.0.1" - port = 1664 - username = os.getenv('USER') - password = "" - daemon_mode = False - if '-d' in options: - daemon_mode = True - if '--watch' in options: - watch_mode = True - else: - watch_mode = False - if '--hostname' in options: - hostname = options['--hostname'] - if '--port' in options: - port = int(options['--port']) - if '--username' in options: - username = options['--username'] - print "Login for %s@%s:%s" % (username, hostname, port) - if '--password' in options: - password = options['--password'] - else: - password = getpass.getpass('password: ') - - if daemon_mode: - print "daemonizing server" - daemonize() - #daemonize('/dev/null','/tmp/daemon.log','/tmp/daemon.log') - - sys.stdout.write ('server started with pid %d\n' % os.getpid() ) - - virtual_screen = ANSI.ANSI (24,80) - child = pxssh.pxssh() - child.login (hostname, username, password) - print 'created shell. command line prompt is', child.PROMPT - #child.sendline ('stty -echo') - #child.setecho(False) - virtual_screen.write (child.before) - virtual_screen.write (child.after) - - if os.path.exists("/tmp/mysock"): os.remove("/tmp/mysock") - s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - localhost = '127.0.0.1' - s.bind('/tmp/mysock') - os.chmod('/tmp/mysock',0777) - print 'Listen' - s.listen(1) - print 'Accept' - #s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - #localhost = '127.0.0.1' - #s.bind((localhost, port)) - #print 'Listen' - #s.listen(1) - - r = roller (0.01, endless_poll, (child, child.PROMPT, virtual_screen)) - r.start() - print "screen poll updater started in background thread" - sys.stdout.flush() - - try: - while True: - conn, addr = s.accept() - print 'Connected by', addr - data = conn.recv(1024) - if data[0]!=':': - cmd = ':sendline' - arg = data.strip() - else: - request = data.split(' ', 1) - if len(request)>1: - cmd = request[0].strip() - arg = request[1].strip() - else: - cmd = request[0].strip() - if cmd == ':exit': - r.cancel() - break - elif cmd == ':sendline': - child.sendline (arg) - #child.prompt(timeout=2) - time.sleep(0.2) - shell_window = str(virtual_screen) - elif cmd == ':send' or cmd==':xsend': - if cmd==':xsend': - arg = arg.decode("hex") - child.send (arg) - time.sleep(0.2) - shell_window = str(virtual_screen) - elif cmd == ':cursor': - shell_window = '%x%x' % (virtual_screen.cur_r, virtual_screen.cur_c) - elif cmd == ':refresh': - shell_window = str(virtual_screen) - - response = [] - response.append (shell_window) - #response = add_cursor_blink (response, row, col) - sent = conn.send('\n'.join(response)) - if watch_mode: print '\n'.join(response) - if sent < len (response): - print "Sent is too short. Some data was cut off." - conn.close() - finally: - r.cancel() - print "cleaning up socket" - s.close() - if os.path.exists("/tmp/mysock"): os.remove("/tmp/mysock") - print "done!" - -def pretty_box (rows, cols, s): - - '''This puts an ASCII text box around the given string, s. - ''' - - top_bot = '+' + '-'*cols + '+\n' - return top_bot + '\n'.join(['|'+line+'|' for line in s.split('\n')]) + '\n' + top_bot - -def error_response (msg): - - response = [] - response.append ('''All commands start with : -:{REQUEST} {ARGUMENT} -{REQUEST} may be one of the following: - :sendline: Run the ARGUMENT followed by a line feed. - :send : send the characters in the ARGUMENT without a line feed. - :refresh : Use to catch up the screen with the shell if state gets out of sync. -Example: - :sendline ls -l -You may also leave off :command and it will be assumed. -Example: - ls -l -is equivalent to: - :sendline ls -l -''') - response.append (msg) - return '\n'.join(response) - -def parse_host_connect_string (hcs): - - '''This parses a host connection string in the form - username:password@hostname:port. All fields are options expcet hostname. A - dictionary is returned with all four keys. Keys that were not included are - set to empty strings ''. Note that if your password has the '@' character - then you must backslash escape it. ''' - - if '@' in hcs: - p = re.compile (r'(?P<username>[^@:]*)(:?)(?P<password>.*)(?!\\)@(?P<hostname>[^:]*):?(?P<port>[0-9]*)') - else: - p = re.compile (r'(?P<username>)(?P<password>)(?P<hostname>[^:]*):?(?P<port>[0-9]*)') - m = p.search (hcs) - d = m.groupdict() - d['password'] = d['password'].replace('\\@','@') - return d - -if __name__ == "__main__": - - try: - start_time = time.time() - print time.asctime() - main() - print time.asctime() - print "TOTAL TIME IN MINUTES:", - print (time.time() - start_time) / 60.0 - except Exception, e: - print str(e) - tb_dump = traceback.format_exc() - print str(tb_dump) - diff --git a/pexpect/examples/cgishell.cgi b/pexpect/examples/cgishell.cgi deleted file mode 100755 index 1e3affc..0000000 --- a/pexpect/examples/cgishell.cgi +++ /dev/null @@ -1,762 +0,0 @@ -#!/usr/bin/python -##!/usr/bin/env python -"""CGI shell server - -This exposes a shell terminal on a web page. -It uses AJAX to send keys and receive screen updates. -The client web browser needs nothing but CSS and Javascript. - - --hostname : sets the remote host name to open an ssh connection to. - --username : sets the user name to login with - --password : (optional) sets the password to login with - --port : set the local port for the server to listen on - --watch : show the virtual screen after each client request - -This project is probably not the most security concious thing I've ever built. -This should be considered an experimental tool -- at best. -""" -import sys,os -sys.path.insert (0,os.getcwd()) # let local modules precede any installed modules -import socket, random, string, traceback, cgi, time, getopt, getpass, threading, resource, signal -import pxssh, pexpect, ANSI - -def exit_with_usage(exit_code=1): - print globals()['__doc__'] - os._exit(exit_code) - -def client (command, host='localhost', port=-1): - """This sends a request to the server and returns the response. - If port <= 0 then host is assumed to be the filename of a Unix domain socket. - If port > 0 then host is an inet hostname. - """ - if port <= 0: - s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - s.connect(host) - else: - s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - s.connect((host, port)) - s.send(command) - data = s.recv (2500) - s.close() - return data - -def server (hostname, username, password, socket_filename='/tmp/server_sock', daemon_mode = True, verbose=False): - """This starts and services requests from a client. - If daemon_mode is True then this forks off a separate daemon process and returns the daemon's pid. - If daemon_mode is False then this does not return until the server is done. - """ - if daemon_mode: - mypid_name = '/tmp/%d.pid' % os.getpid() - daemon_pid = daemonize(daemon_pid_filename=mypid_name) - time.sleep(1) - if daemon_pid != 0: - os.unlink(mypid_name) - return daemon_pid - - virtual_screen = ANSI.ANSI (24,80) - child = pxssh.pxssh() - try: - child.login (hostname, username, password, login_naked=True) - except: - return - if verbose: print 'login OK' - virtual_screen.write (child.before) - virtual_screen.write (child.after) - - if os.path.exists(socket_filename): os.remove(socket_filename) - s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - s.bind(socket_filename) - os.chmod(socket_filename, 0777) - if verbose: print 'Listen' - s.listen(1) - - r = roller (endless_poll, (child, child.PROMPT, virtual_screen)) - r.start() - if verbose: print "started screen-poll-updater in background thread" - sys.stdout.flush() - try: - while True: - conn, addr = s.accept() - if verbose: print 'Connected by', addr - data = conn.recv(1024) - request = data.split(' ', 1) - if len(request)>1: - cmd = request[0].strip() - arg = request[1].strip() - else: - cmd = request[0].strip() - arg = '' - - if cmd == 'exit': - r.cancel() - break - elif cmd == 'sendline': - child.sendline (arg) - time.sleep(0.1) - shell_window = str(virtual_screen) - elif cmd == 'send' or cmd=='xsend': - if cmd=='xsend': - arg = arg.decode("hex") - child.send (arg) - time.sleep(0.1) - shell_window = str(virtual_screen) - elif cmd == 'cursor': - shell_window = '%x,%x' % (virtual_screen.cur_r, virtual_screen.cur_c) - elif cmd == 'refresh': - shell_window = str(virtual_screen) - elif cmd == 'hash': - shell_window = str(hash(str(virtual_screen))) - - response = [] - response.append (shell_window) - if verbose: print '\n'.join(response) - sent = conn.send('\n'.join(response)) - if sent < len (response): - if verbose: print "Sent is too short. Some data was cut off." - conn.close() - except e: - pass - r.cancel() - if verbose: print "cleaning up socket" - s.close() - if os.path.exists(socket_filename): os.remove(socket_filename) - if verbose: print "server done!" - -class roller (threading.Thread): - """This class continuously loops a function in a thread. - This is basically a thin layer around Thread with a - while loop and a cancel. - """ - def __init__(self, function, args=[], kwargs={}): - threading.Thread.__init__(self) - self.function = function - self.args = args - self.kwargs = kwargs - self.finished = threading.Event() - def cancel(self): - """Stop the roller.""" - self.finished.set() - def run(self): - while not self.finished.isSet(): - self.function(*self.args, **self.kwargs) - -def endless_poll (child, prompt, screen, refresh_timeout=0.1): - """This keeps the screen updated with the output of the child. - This will be run in a separate thread. See roller class. - """ - #child.logfile_read = screen - try: - s = child.read_nonblocking(4000, 0.1) - screen.write(s) - except: - pass - -def daemonize (stdin=None, stdout=None, stderr=None, daemon_pid_filename=None): - """This runs the current process in the background as a daemon. - The arguments stdin, stdout, stderr allow you to set the filename that the daemon reads and writes to. - If they are set to None then all stdio for the daemon will be directed to /dev/null. - If daemon_pid_filename is set then the pid of the daemon will be written to it as plain text - and the pid will be returned. If daemon_pid_filename is None then this will return None. - """ - UMASK = 0 - WORKINGDIR = "/" - MAXFD = 1024 - - # The stdio file descriptors are redirected to /dev/null by default. - if hasattr(os, "devnull"): - DEVNULL = os.devnull - else: - DEVNULL = "/dev/null" - if stdin is None: stdin = DEVNULL - if stdout is None: stdout = DEVNULL - if stderr is None: stderr = DEVNULL - - try: - pid = os.fork() - except OSError, e: - raise Exception, "%s [%d]" % (e.strerror, e.errno) - - if pid != 0: # The first child. - os.waitpid(pid,0) - if daemon_pid_filename is not None: - daemon_pid = int(file(daemon_pid_filename,'r').read()) - return daemon_pid - else: - return None - - # first child - os.setsid() - signal.signal(signal.SIGHUP, signal.SIG_IGN) - - try: - pid = os.fork() # fork second child - except OSError, e: - raise Exception, "%s [%d]" % (e.strerror, e.errno) - - if pid != 0: - if daemon_pid_filename is not None: - file(daemon_pid_filename,'w').write(str(pid)) - os._exit(0) # exit parent (the first child) of the second child. - - # second child - os.chdir(WORKINGDIR) - os.umask(UMASK) - - maxfd = resource.getrlimit(resource.RLIMIT_NOFILE)[1] - if maxfd == resource.RLIM_INFINITY: - maxfd = MAXFD - - # close all file descriptors - for fd in xrange(0, maxfd): - try: - os.close(fd) - except OSError: # fd wasn't open to begin with (ignored) - pass - - os.open (DEVNULL, os.O_RDWR) # standard input - - # redirect standard file descriptors - si = open(stdin, 'r') - so = open(stdout, 'a+') - se = open(stderr, 'a+', 0) - os.dup2(si.fileno(), sys.stdin.fileno()) - os.dup2(so.fileno(), sys.stdout.fileno()) - os.dup2(se.fileno(), sys.stderr.fileno()) - - return 0 - -def client_cgi (): - """This handles the request if this script was called as a cgi. - """ - sys.stderr = sys.stdout - ajax_mode = False - TITLE="Shell" - SHELL_OUTPUT="" - SID="NOT" - print "Content-type: text/html;charset=utf-8\r\n" - try: - form = cgi.FieldStorage() - if form.has_key('ajax'): - ajax_mode = True - ajax_cmd = form['ajax'].value - SID=form['sid'].value - if ajax_cmd == 'send': - command = 'xsend' - arg = form['arg'].value.encode('hex') - result = client (command + ' ' + arg, '/tmp/'+SID) - print result - elif ajax_cmd == 'refresh': - command = 'refresh' - result = client (command, '/tmp/'+SID) - print result - elif ajax_cmd == 'cursor': - command = 'cursor' - result = client (command, '/tmp/'+SID) - print result - elif ajax_cmd == 'exit': - command = 'exit' - result = client (command, '/tmp/'+SID) - print result - elif ajax_cmd == 'hash': - command = 'hash' - result = client (command, '/tmp/'+SID) - print result - elif not form.has_key('sid'): - SID=random_sid() - print LOGIN_HTML % locals(); - else: - SID=form['sid'].value - if form.has_key('start_server'): - USERNAME = form['username'].value - PASSWORD = form['password'].value - dpid = server ('127.0.0.1', USERNAME, PASSWORD, '/tmp/'+SID) - SHELL_OUTPUT="daemon pid: " + str(dpid) - else: - if form.has_key('cli'): - command = 'sendline ' + form['cli'].value - else: - command = 'sendline' - SHELL_OUTPUT = client (command, '/tmp/'+SID) - print CGISH_HTML % locals() - except: - tb_dump = traceback.format_exc() - if ajax_mode: - print str(tb_dump) - else: - SHELL_OUTPUT=str(tb_dump) - print CGISH_HTML % locals() - -def server_cli(): - """This is the command line interface to starting the server. - This handles things if the script was not called as a CGI - (if you run it from the command line). - """ - try: - optlist, args = getopt.getopt(sys.argv[1:], 'h?d', ['help','h','?', 'hostname=', 'username=', 'password=', 'port=', 'watch']) - except Exception, e: - print str(e) - exit_with_usage() - - command_line_options = dict(optlist) - options = dict(optlist) - # There are a million ways to cry for help. These are but a few of them. - if [elem for elem in command_line_options if elem in ['-h','--h','-?','--?','--help']]: - exit_with_usage(0) - - hostname = "127.0.0.1" - #port = 1664 - username = os.getenv('USER') - password = "" - daemon_mode = False - if '-d' in options: - daemon_mode = True - if '--watch' in options: - watch_mode = True - else: - watch_mode = False - if '--hostname' in options: - hostname = options['--hostname'] - if '--port' in options: - port = int(options['--port']) - if '--username' in options: - username = options['--username'] - if '--password' in options: - password = options['--password'] - else: - password = getpass.getpass('password: ') - - server (hostname, username, password, '/tmp/mysock', daemon_mode) - -def random_sid (): - a=random.randint(0,65535) - b=random.randint(0,65535) - return '%04x%04x.sid' % (a,b) - -def parse_host_connect_string (hcs): - """This parses a host connection string in the form - username:password@hostname:port. All fields are options expcet hostname. A - dictionary is returned with all four keys. Keys that were not included are - set to empty strings ''. Note that if your password has the '@' character - then you must backslash escape it. - """ - if '@' in hcs: - p = re.compile (r'(?P<username>[^@:]*)(:?)(?P<password>.*)(?!\\)@(?P<hostname>[^:]*):?(?P<port>[0-9]*)') - else: - p = re.compile (r'(?P<username>)(?P<password>)(?P<hostname>[^:]*):?(?P<port>[0-9]*)') - m = p.search (hcs) - d = m.groupdict() - d['password'] = d['password'].replace('\\@','@') - return d - -def pretty_box (s, rows=24, cols=80): - """This puts an ASCII text box around the given string. - """ - top_bot = '+' + '-'*cols + '+\n' - return top_bot + '\n'.join(['|'+line+'|' for line in s.split('\n')]) + '\n' + top_bot - -def main (): - if os.getenv('REQUEST_METHOD') is None: - server_cli() - else: - client_cgi() - -# It's mostly HTML and Javascript from here on out. -CGISH_HTML="""<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> -<html> -<head> -<title>%(TITLE)s %(SID)s</title> -<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> -<style type=text/css> -a {color: #9f9; text-decoration: none} -a:hover {color: #0f0} -hr {color: #0f0} -html,body,textarea,input,form -{ -font-family: "Courier New", Courier, mono; -font-size: 8pt; -color: #0c0; -background-color: #020; -margin:0; -padding:0; -border:0; -} -input { background-color: #010; } -textarea { -border-width:1; -border-style:solid; -border-color:#0c0; -padding:3; -margin:3; -} -</style> - -<script language="JavaScript"> -function focus_first() -{if (document.forms.length > 0) -{var TForm = document.forms[0]; -for (i=0;i<TForm.length;i++){ -if ((TForm.elements[i].type=="text")|| -(TForm.elements[i].type=="textarea")|| -(TForm.elements[i].type.toString().charAt(0)=="s")) -{document.forms[0].elements[i].focus();break;}}}} - -// JavaScript Virtual Keyboard -// If you like this code then buy me a sandwich. -// Noah Spurrier <noah@noah.org> -var flag_shift=0; -var flag_shiftlock=0; -var flag_ctrl=0; -var ButtonOnColor="#ee0"; - -function init () -{ - // hack to set quote key to show both single quote and double quote - document.form['quote'].value = "'" + ' "'; - //refresh_screen(); - poll(); - document.form["cli"].focus(); -} -function get_password () -{ - var username = prompt("username?",""); - var password = prompt("password?",""); - start_server (username, password); -} -function multibrowser_ajax () -{ - var xmlHttp = false; -/*@cc_on @*/ -/*@if (@_jscript_version >= 5) - try - { - xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); - } - catch (e) - { - try - { - xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); - } - catch (e2) - { - xmlHttp = false; - } - } -@end @*/ - - if (!xmlHttp && typeof XMLHttpRequest != 'undefined') - { - xmlHttp = new XMLHttpRequest(); - } - return xmlHttp; -} -function load_url_to_screen(url) -{ - xmlhttp = multibrowser_ajax(); - //window.XMLHttpRequest?new XMLHttpRequest(): new ActiveXObject("Microsoft.XMLHTTP"); - xmlhttp.onreadystatechange = update_virtual_screen; - xmlhttp.open("GET", url); - xmlhttp.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT"); - xmlhttp.send(null); -} -function update_virtual_screen() -{ - if ((xmlhttp.readyState == 4) && (xmlhttp.status == 200)) - { - var screen_text = xmlhttp.responseText; - document.form["screen_text"].value = screen_text; - //var json_data = json_parse(xmlhttp.responseText); - } -} -function poll() -{ - refresh_screen(); - timerID = setTimeout("poll()", 2000); - // clearTimeout(timerID); -} -//function start_server (username, password) -//{ -// load_url_to_screen('cgishell.cgi?ajax=serverstart&username=' + escape(username) + '&password=' + escape(password); -//} -function refresh_screen() -{ - load_url_to_screen('cgishell.cgi?ajax=refresh&sid=%(SID)s'); -} -function query_hash() -{ - load_url_to_screen('cgishell.cgi?ajax=hash&sid=%(SID)s'); -} -function query_cursor() -{ - load_url_to_screen('cgishell.cgi?ajax=cursor&sid=%(SID)s'); -} -function exit_server() -{ - load_url_to_screen('cgishell.cgi?ajax=exit&sid=%(SID)s'); -} -function type_key (chars) -{ - var ch = '?'; - if (flag_shiftlock || flag_shift) - { - ch = chars.substr(1,1); - } - else if (flag_ctrl) - { - ch = chars.substr(2,1); - } - else - { - ch = chars.substr(0,1); - } - load_url_to_screen('cgishell.cgi?ajax=send&sid=%(SID)s&arg=' + escape(ch)); - if (flag_shift || flag_ctrl) - { - flag_shift = 0; - flag_ctrl = 0; - } - update_button_colors(); -} - -function key_shiftlock() -{ - flag_ctrl = 0; - flag_shift = 0; - if (flag_shiftlock) - { - flag_shiftlock = 0; - } - else - { - flag_shiftlock = 1; - } - update_button_colors(); -} - -function key_shift() -{ - if (flag_shift) - { - flag_shift = 0; - } - else - { - flag_ctrl = 0; - flag_shiftlock = 0; - flag_shift = 1; - } - update_button_colors(); -} -function key_ctrl () -{ - if (flag_ctrl) - { - flag_ctrl = 0; - } - else - { - flag_ctrl = 1; - flag_shiftlock = 0; - flag_shift = 0; - } - - update_button_colors(); -} -function update_button_colors () -{ - if (flag_ctrl) - { - document.form['Ctrl'].style.backgroundColor = ButtonOnColor; - document.form['Ctrl2'].style.backgroundColor = ButtonOnColor; - } - else - { - document.form['Ctrl'].style.backgroundColor = document.form.style.backgroundColor; - document.form['Ctrl2'].style.backgroundColor = document.form.style.backgroundColor; - } - if (flag_shift) - { - document.form['Shift'].style.backgroundColor = ButtonOnColor; - document.form['Shift2'].style.backgroundColor = ButtonOnColor; - } - else - { - document.form['Shift'].style.backgroundColor = document.form.style.backgroundColor; - document.form['Shift2'].style.backgroundColor = document.form.style.backgroundColor; - } - if (flag_shiftlock) - { - document.form['ShiftLock'].style.backgroundColor = ButtonOnColor; - } - else - { - document.form['ShiftLock'].style.backgroundColor = document.form.style.backgroundColor; - } - -} -function keyHandler(e) -{ - var pressedKey; - if (document.all) { e = window.event; } - if (document.layers) { pressedKey = e.which; } - if (document.all) { pressedKey = e.keyCode; } - pressedCharacter = String.fromCharCode(pressedKey); - type_key(pressedCharacter+pressedCharacter+pressedCharacter); - alert(pressedCharacter); -// alert(' Character = ' + pressedCharacter + ' [Decimal value = ' + pressedKey + ']'); -} -//document.onkeypress = keyHandler; -//if (document.layers) -// document.captureEvents(Event.KEYPRESS); -//http://sniptools.com/jskeys -//document.onkeyup = KeyCheck; -function KeyCheck(e) -{ - var KeyID = (window.event) ? event.keyCode : e.keyCode; - type_key(String.fromCharCode(KeyID)); - e.cancelBubble = true; - window.event.cancelBubble = true; -} -</script> - -</head> - -<body onload="init()"> -<form id="form" name="form" action="/cgi-bin/cgishell.cgi" method="POST"> -<input name="sid" value="%(SID)s" type="hidden"> -<textarea name="screen_text" cols="81" rows="25">%(SHELL_OUTPUT)s</textarea> -<hr noshade="1"> - <input name="cli" id="cli" type="text" size="80"><br> -<table border="0" align="left"> -<tr> -<td width="86%%" align="center"> - <input name="submit" type="submit" value="Submit"> - <input name="refresh" type="button" value="REFRESH" onclick="refresh_screen()"> - <input name="refresh" type="button" value="CURSOR" onclick="query_cursor()"> - <input name="hash" type="button" value="HASH" onclick="query_hash()"> - <input name="exit" type="button" value="EXIT" onclick="exit_server()"> - <br> - <input type="button" value="Esc" onclick="type_key('\\x1b\\x1b')" /> - <input type="button" value="` ~" onclick="type_key('`~')" /> - <input type="button" value="1!" onclick="type_key('1!')" /> - <input type="button" value="2@" onclick="type_key('2@\\x00')" /> - <input type="button" value="3#" onclick="type_key('3#')" /> - <input type="button" value="4$" onclick="type_key('4$')" /> - <input type="button" value="5%%" onclick="type_key('5%%')" /> - <input type="button" value="6^" onclick="type_key('6^\\x1E')" /> - <input type="button" value="7&" onclick="type_key('7&')" /> - <input type="button" value="8*" onclick="type_key('8*')" /> - <input type="button" value="9(" onclick="type_key('9(')" /> - <input type="button" value="0)" onclick="type_key('0)')" /> - <input type="button" value="-_" onclick="type_key('-_\\x1F')" /> - <input type="button" value="=+" onclick="type_key('=+')" /> - <input type="button" value="BkSp" onclick="type_key('\\x08\\x08\\x08')" /> - <br> - <input type="button" value="Tab" onclick="type_key('\\t\\t')" /> - <input type="button" value="Q" onclick="type_key('qQ\\x11')" /> - <input type="button" value="W" onclick="type_key('wW\\x17')" /> - <input type="button" value="E" onclick="type_key('eE\\x05')" /> - <input type="button" value="R" onclick="type_key('rR\\x12')" /> - <input type="button" value="T" onclick="type_key('tT\\x14')" /> - <input type="button" value="Y" onclick="type_key('yY\\x19')" /> - <input type="button" value="U" onclick="type_key('uU\\x15')" /> - <input type="button" value="I" onclick="type_key('iI\\x09')" /> - <input type="button" value="O" onclick="type_key('oO\\x0F')" /> - <input type="button" value="P" onclick="type_key('pP\\x10')" /> - <input type="button" value="[ {" onclick="type_key('[{\\x1b')" /> - <input type="button" value="] }" onclick="type_key(']}\\x1d')" /> - <input type="button" value="\\ |" onclick="type_key('\\\\|\\x1c')" /> - <br> - <input type="button" id="Ctrl" value="Ctrl" onclick="key_ctrl()" /> - <input type="button" value="A" onclick="type_key('aA\\x01')" /> - <input type="button" value="S" onclick="type_key('sS\\x13')" /> - <input type="button" value="D" onclick="type_key('dD\\x04')" /> - <input type="button" value="F" onclick="type_key('fF\\x06')" /> - <input type="button" value="G" onclick="type_key('gG\\x07')" /> - <input type="button" value="H" onclick="type_key('hH\\x08')" /> - <input type="button" value="J" onclick="type_key('jJ\\x0A')" /> - <input type="button" value="K" onclick="type_key('kK\\x0B')" /> - <input type="button" value="L" onclick="type_key('lL\\x0C')" /> - <input type="button" value="; :" onclick="type_key(';:')" /> - <input type="button" id="quote" value="'" onclick="type_key('\\x27\\x22')" /> - <input type="button" value="Enter" onclick="type_key('\\n\\n')" /> - <br> - <input type="button" id="ShiftLock" value="Caps Lock" onclick="key_shiftlock()" /> - <input type="button" id="Shift" value="Shift" onclick="key_shift()" /> - <input type="button" value="Z" onclick="type_key('zZ\\x1A')" /> - <input type="button" value="X" onclick="type_key('xX\\x18')" /> - <input type="button" value="C" onclick="type_key('cC\\x03')" /> - <input type="button" value="V" onclick="type_key('vV\\x16')" /> - <input type="button" value="B" onclick="type_key('bB\\x02')" /> - <input type="button" value="N" onclick="type_key('nN\\x0E')" /> - <input type="button" value="M" onclick="type_key('mM\\x0D')" /> - <input type="button" value=", <" onclick="type_key(',<')" /> - <input type="button" value=". >" onclick="type_key('.>')" /> - <input type="button" value="/ ?" onclick="type_key('/?')" /> - <input type="button" id="Shift2" value="Shift" onclick="key_shift()" /> - <input type="button" id="Ctrl2" value="Ctrl" onclick="key_ctrl()" /> - <br> - <input type="button" value=" FINAL FRONTIER " onclick="type_key(' ')" /> -</td> -</tr> -</table> -</form> -</body> -</html> -""" - -LOGIN_HTML="""<html> -<head> -<title>Shell Login</title> -<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> -<style type=text/css> -a {color: #9f9; text-decoration: none} -a:hover {color: #0f0} -hr {color: #0f0} -html,body,textarea,input,form -{ -font-family: "Courier New", Courier, mono; -font-size: 8pt; -color: #0c0; -background-color: #020; -margin:3; -padding:0; -border:0; -} -input { background-color: #010; } -input,textarea { -border-width:1; -border-style:solid; -border-color:#0c0; -padding:3; -margin:3; -} -</style> -<script language="JavaScript"> -function init () -{ - document.login_form["username"].focus(); -} -</script> -</head> -<body onload="init()"> -<form name="login_form" method="POST"> -<input name="start_server" value="1" type="hidden"> -<input name="sid" value="%(SID)s" type="hidden"> -username: <input name="username" type="text" size="30"><br> -password: <input name="password" type="password" size="30"><br> -<input name="submit" type="submit" value="enter"> -</form> -<br> -</body> -</html> -""" - -if __name__ == "__main__": - try: - main() - except Exception, e: - print str(e) - tb_dump = traceback.format_exc() - print str(tb_dump) - diff --git a/pexpect/examples/chess.py b/pexpect/examples/chess.py deleted file mode 100755 index 193dbd8..0000000 --- a/pexpect/examples/chess.py +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env python - -'''This demonstrates controlling a screen oriented application (curses). -It starts two instances of gnuchess and then pits them against each other. - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import pexpect -import string -import ANSI - -REGEX_MOVE = '(?:[a-z]|\x1b\[C)(?:[0-9]|\x1b\[C)(?:[a-z]|\x1b\[C)(?:[0-9]|\x1b\[C)' -REGEX_MOVE_PART = '(?:[0-9]|\x1b\[C)(?:[a-z]|\x1b\[C)(?:[0-9]|\x1b\[C)' - -class Chess: - - def __init__(self, engine = "/usr/local/bin/gnuchess -a -h 1"): - self.child = pexpect.spawn (engine) - self.term = ANSI.ANSI () - - self.child.expect ('Chess') - if self.child.after != 'Chess': - raise IOError, 'incompatible chess program' - self.term.process_list (self.before) - self.term.process_list (self.after) - self.last_computer_move = '' - def read_until_cursor (self, r,c) - while 1: - self.child.read(1, 60) - self.term.process (c) - if self.term.cur_r == r and self.term.cur_c == c: - return 1 - - def do_first_move (self, move): - self.child.expect ('Your move is') - self.child.sendline (move) - self.term.process_list (self.before) - self.term.process_list (self.after) - return move - - def do_move (self, move): - read_until_cursor (19,60) - #self.child.expect ('\[19;60H') - self.child.sendline (move) - print 'do_move' move - return move - - def get_first_computer_move (self): - self.child.expect ('My move is') - self.child.expect (REGEX_MOVE) -# print '', self.child.after - return self.child.after - - def get_computer_move (self): - print 'Here' - i = self.child.expect (['\[17;59H', '\[17;58H']) - print i - if i == 0: - self.child.expect (REGEX_MOVE) - if len(self.child.after) < 4: - self.child.after = self.child.after + self.last_computer_move[3] - if i == 1: - self.child.expect (REGEX_MOVE_PART) - self.child.after = self.last_computer_move[0] + self.child.after - print '', self.child.after - self.last_computer_move = self.child.after - return self.child.after - - def switch (self): - self.child.sendline ('switch') - - def set_depth (self, depth): - self.child.sendline ('depth') - self.child.expect ('depth=') - self.child.sendline ('%d' % depth) - - def quit(self): - self.child.sendline ('quit') -import sys, os -print 'Starting...' -white = Chess() -white.child.echo = 1 -white.child.expect ('Your move is') -white.set_depth(2) -white.switch() - -move_white = white.get_first_computer_move() -print 'first move white:', move_white - -white.do_move ('e7e5') -move_white = white.get_computer_move() -print 'move white:', move_white -white.do_move ('f8c5') -move_white = white.get_computer_move() -print 'move white:', move_white -white.do_move ('b8a6') -move_white = white.get_computer_move() -print 'move white:', move_white - -sys.exit(1) - - - -black = Chess() -white = Chess() -white.child.expect ('Your move is') -white.switch() - -move_white = white.get_first_computer_move() -print 'first move white:', move_white - -black.do_first_move (move_white) -move_black = black.get_first_computer_move() -print 'first move black:', move_black - -white.do_move (move_black) - -done = 0 -while not done: - move_white = white.get_computer_move() - print 'move white:', move_white - - black.do_move (move_white) - move_black = black.get_computer_move() - print 'move black:', move_black - - white.do_move (move_black) - print 'tail of loop' - -g.quit() - - diff --git a/pexpect/examples/chess2.py b/pexpect/examples/chess2.py deleted file mode 100755 index 7fe959a..0000000 --- a/pexpect/examples/chess2.py +++ /dev/null @@ -1,149 +0,0 @@ -#!/usr/bin/env python - -'''This demonstrates controlling a screen oriented application (curses). -It starts two instances of gnuchess and then pits them against each other. - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import pexpect -import string -import ANSI -import sys, os, time - -class Chess: - - def __init__(self, engine = "/usr/local/bin/gnuchess -a -h 1"): - self.child = pexpect.spawn (engine) - self.term = ANSI.ANSI () - - #self.child.expect ('Chess') - #if self.child.after != 'Chess': - # raise IOError, 'incompatible chess program' - #self.term.process_list (self.child.before) - #self.term.process_list (self.child.after) - - self.last_computer_move = '' - - def read_until_cursor (self, r,c, e=0): - '''Eventually something like this should move into the screen class or - a subclass. Maybe a combination of pexpect and screen... - ''' - fout = open ('log','a') - while self.term.cur_r != r or self.term.cur_c != c: - try: - k = self.child.read(1, 10) - except Exception, e: - print 'EXCEPTION, (r,c):(%d,%d)\n' %(self.term.cur_r, self.term.cur_c) - sys.stdout.flush() - self.term.process (k) - fout.write ('(r,c):(%d,%d)\n' %(self.term.cur_r, self.term.cur_c)) - fout.flush() - if e: - sys.stdout.write (k) - sys.stdout.flush() - if self.term.cur_r == r and self.term.cur_c == c: - fout.close() - return 1 - print 'DIDNT EVEN HIT.' - fout.close() - return 1 - - def expect_region (self): - '''This is another method that would be moved into the - screen class. - ''' - pass - def do_scan (self): - fout = open ('log','a') - while 1: - c = self.child.read(1,10) - self.term.process (c) - fout.write ('(r,c):(%d,%d)\n' %(self.term.cur_r, self.term.cur_c)) - fout.flush() - sys.stdout.write (c) - sys.stdout.flush() - - def do_move (self, move, e = 0): - time.sleep(1) - self.read_until_cursor (19,60, e) - self.child.sendline (move) - - def wait (self, color): - while 1: - r = self.term.get_region (14,50,14,60)[0] - r = r.strip() - if r == color: - return - time.sleep (1) - - def parse_computer_move (self, s): - i = s.find ('is: ') - cm = s[i+3:i+9] - return cm - def get_computer_move (self, e = 0): - time.sleep(1) - self.read_until_cursor (19,60, e) - time.sleep(1) - r = self.term.get_region (17,50,17,62)[0] - cm = self.parse_computer_move (r) - return cm - - def switch (self): - print 'switching' - self.child.sendline ('switch') - - def set_depth (self, depth): - self.child.sendline ('depth') - self.child.expect ('depth=') - self.child.sendline ('%d' % depth) - - def quit(self): - self.child.sendline ('quit') - -def LOG (s): - print s - sys.stdout.flush () - fout = open ('moves.log', 'a') - fout.write (s + '\n') - fout.close() - -print 'Starting...' - -black = Chess() -white = Chess() -white.read_until_cursor (19,60,1) -white.switch() - -done = 0 -while not done: - white.wait ('Black') - move_white = white.get_computer_move(1) - LOG ( 'move white:'+ move_white ) - - black.do_move (move_white) - black.wait ('White') - move_black = black.get_computer_move() - LOG ( 'move black:'+ move_black ) - - white.do_move (move_black, 1) - -g.quit() - - diff --git a/pexpect/examples/chess3.py b/pexpect/examples/chess3.py deleted file mode 100755 index f60ab0a..0000000 --- a/pexpect/examples/chess3.py +++ /dev/null @@ -1,156 +0,0 @@ -#!/usr/bin/env python - -'''This demonstrates controlling a screen oriented application (curses). -It starts two instances of gnuchess and then pits them against each other. - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import pexpect -import string -import ANSI - -REGEX_MOVE = '(?:[a-z]|\x1b\[C)(?:[0-9]|\x1b\[C)(?:[a-z]|\x1b\[C)(?:[0-9]|\x1b\[C)' -REGEX_MOVE_PART = '(?:[0-9]|\x1b\[C)(?:[a-z]|\x1b\[C)(?:[0-9]|\x1b\[C)' - -class Chess: - - def __init__(self, engine = "/usr/local/bin/gnuchess -a -h 1"): - self.child = pexpect.spawn (engine) - self.term = ANSI.ANSI () - -# self.child.expect ('Chess') - # if self.child.after != 'Chess': - # raise IOError, 'incompatible chess program' - # self.term.process_list (self.before) - # self.term.process_list (self.after) - self.last_computer_move = '' - def read_until_cursor (self, r,c): - fout = open ('log','a') - while 1: - k = self.child.read(1, 10) - self.term.process (k) - fout.write ('(r,c):(%d,%d)\n' %(self.term.cur_r, self.term.cur_c)) - fout.flush() - if self.term.cur_r == r and self.term.cur_c == c: - fout.close() - return 1 - sys.stdout.write (k) - sys.stdout.flush() - - def do_scan (self): - fout = open ('log','a') - while 1: - c = self.child.read(1,10) - self.term.process (c) - fout.write ('(r,c):(%d,%d)\n' %(self.term.cur_r, self.term.cur_c)) - fout.flush() - sys.stdout.write (c) - sys.stdout.flush() - - def do_move (self, move): - self.read_until_cursor (19,60) - self.child.sendline (move) - return move - - def get_computer_move (self): - print 'Here' - i = self.child.expect (['\[17;59H', '\[17;58H']) - print i - if i == 0: - self.child.expect (REGEX_MOVE) - if len(self.child.after) < 4: - self.child.after = self.child.after + self.last_computer_move[3] - if i == 1: - self.child.expect (REGEX_MOVE_PART) - self.child.after = self.last_computer_move[0] + self.child.after - print '', self.child.after - self.last_computer_move = self.child.after - return self.child.after - - def switch (self): - self.child.sendline ('switch') - - def set_depth (self, depth): - self.child.sendline ('depth') - self.child.expect ('depth=') - self.child.sendline ('%d' % depth) - - def quit(self): - self.child.sendline ('quit') -import sys, os -print 'Starting...' -white = Chess() -white.do_move('b2b4') -white.read_until_cursor (19,60) -c1 = white.term.get_abs(17,58) -c2 = white.term.get_abs(17,59) -c3 = white.term.get_abs(17,60) -c4 = white.term.get_abs(17,61) -fout = open ('log','a') -fout.write ('Computer:%s%s%s%s\n' %(c1,c2,c3,c4)) -fout.close() -white.do_move('c2c4') -white.read_until_cursor (19,60) -c1 = white.term.get_abs(17,58) -c2 = white.term.get_abs(17,59) -c3 = white.term.get_abs(17,60) -c4 = white.term.get_abs(17,61) -fout = open ('log','a') -fout.write ('Computer:%s%s%s%s\n' %(c1,c2,c3,c4)) -fout.close() -white.do_scan () - -#white.do_move ('b8a6') -#move_white = white.get_computer_move() -#print 'move white:', move_white - -sys.exit(1) - - - -black = Chess() -white = Chess() -white.child.expect ('Your move is') -white.switch() - -move_white = white.get_first_computer_move() -print 'first move white:', move_white - -black.do_first_move (move_white) -move_black = black.get_first_computer_move() -print 'first move black:', move_black - -white.do_move (move_black) - -done = 0 -while not done: - move_white = white.get_computer_move() - print 'move white:', move_white - - black.do_move (move_white) - move_black = black.get_computer_move() - print 'move black:', move_black - - white.do_move (move_black) - print 'tail of loop' - -g.quit() - - diff --git a/pexpect/examples/df.py b/pexpect/examples/df.py deleted file mode 100755 index d565df3..0000000 --- a/pexpect/examples/df.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env python - -'''This collects filesystem capacity info using the 'df' command. Tuples of -filesystem name and percentage are stored in a list. A simple report is -printed. Filesystems over 95% capacity are highlighted. Note that this does not -parse filesystem names after the first space, so names with spaces in them will -be truncated. This will produce ambiguous results for automount filesystems on -Apple OSX. - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import pexpect - -child = pexpect.spawn ('df') - -# parse 'df' output into a list. -pattern = "\n(\S+).*?([0-9]+)%" -filesystem_list = [] -for dummy in range (0, 1000): - i = child.expect ([pattern, pexpect.EOF]) - if i == 0: - filesystem_list.append (child.match.groups()) - else: - break - -# Print report -print -for m in filesystem_list: - s = "Filesystem %s is at %s%%" % (m[0], m[1]) - # highlight filesystems over 95% capacity - if int(m[1]) > 95: - s = '! ' + s - else: - s = ' ' + s - print s - diff --git a/pexpect/examples/fix_cvs_files.py b/pexpect/examples/fix_cvs_files.py deleted file mode 100755 index 733c39a..0000000 --- a/pexpect/examples/fix_cvs_files.py +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/env python - -'''This is for cleaning up binary files improperly added to CVS. This script -scans the given path to find binary files; checks with CVS to see if the sticky -options are set to -kb; finally if sticky options are not -kb then uses 'cvs -admin' to set the -kb option. - -This script ignores CVS directories, symbolic links, and files not known under -CVS control (cvs status is 'Unknown'). - -Run this on a CHECKED OUT module sandbox, not on the repository itself. After -if fixes the sticky options on any files you should manually do a 'cvs commit' -to accept the changes. Then be sure to have all users do a 'cvs up -A' to -update the Sticky Option status. - -Noah Spurrier -20030426 - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import os, sys, time -import pexpect - -VERBOSE = 1 - -def is_binary (filename): - - '''Assume that any file with a character where the 8th bit is set is - binary. ''' - - fin = open(filename, 'rb') - wholething = fin.read() - fin.close() - for c in wholething: - if ord(c) & 0x80: - return 1 - return 0 - -def is_kb_sticky (filename): - - '''This checks if 'cvs status' reports '-kb' for Sticky options. If the - Sticky Option status is '-ks' then this returns 1. If the status is - 'Unknown' then it returns 1. Otherwise 0 is returned. ''' - - try: - s = pexpect.spawn ('cvs status %s' % filename) - i = s.expect (['Sticky Options:\s*(.*)\r\n', 'Status: Unknown']) - if i==1 and VERBOSE: - print 'File not part of CVS repository:', filename - return 1 # Pretend it's OK. - if s.match.group(1) == '-kb': - return 1 - s = None - except: - print 'Something went wrong trying to run external cvs command.' - print ' cvs status %s' % filename - print 'The cvs command returned:' - print s.before - return 0 - -def cvs_admin_kb (filename): - - '''This uses 'cvs admin' to set the '-kb' sticky option. ''' - - s = pexpect.run ('cvs admin -kb %s' % filename) - # There is a timing issue. If I run 'cvs admin' too quickly - # cvs sometimes has trouble obtaining the directory lock. - time.sleep(1) - -def walk_and_clean_cvs_binaries (arg, dirname, names): - - '''This contains the logic for processing files. This is the os.path.walk - callback. This skips dirnames that end in CVS. ''' - - if len(dirname)>3 and dirname[-3:]=='CVS': - return - for n in names: - fullpath = os.path.join (dirname, n) - if os.path.isdir(fullpath) or os.path.islink(fullpath): - continue - if is_binary(fullpath): - if not is_kb_sticky (fullpath): - if VERBOSE: print fullpath - cvs_admin_kb (fullpath) - -def main (): - - if len(sys.argv) == 1: - root = '.' - else: - root = sys.argv[1] - os.path.walk (root, walk_and_clean_cvs_binaries, None) - -if __name__ == '__main__': - main () - diff --git a/pexpect/examples/ftp.py b/pexpect/examples/ftp.py deleted file mode 100755 index 18e444e..0000000 --- a/pexpect/examples/ftp.py +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env python - -'''This demonstrates an FTP "bookmark". This connects to an ftp site; does a -few ftp stuff; and then gives the user interactive control over the session. In -this case the "bookmark" is to a directory on the OpenBSD ftp server. It puts -you in the i386 packages directory. You can easily modify this for other sites. - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import pexpect -import sys - -child = pexpect.spawn('ftp ftp.openbsd.org') -child.expect('(?i)name .*: ') -child.sendline('anonymous') -child.expect('(?i)password') -child.sendline('pexpect@sourceforge.net') -child.expect('ftp> ') -child.sendline('cd /pub/OpenBSD/3.7/packages/i386') -child.expect('ftp> ') -child.sendline('bin') -child.expect('ftp> ') -child.sendline('prompt') -child.expect('ftp> ') -child.sendline('pwd') -child.expect('ftp> ') -print("Escape character is '^]'.\n") -sys.stdout.write (child.after) -sys.stdout.flush() -child.interact() # Escape character defaults to ^] -# At this point this script blocks until the user presses the escape character -# or until the child exits. The human user and the child should be talking -# to each other now. - -# At this point the script is running again. -print 'Left interactve mode.' - -# The rest is not strictly necessary. This just demonstrates a few functions. -# This makes sure the child is dead; although it would be killed when Python exits. -if child.isalive(): - child.sendline('bye') # Try to ask ftp child to exit. - child.close() -# Print the final state of the child. Normally isalive() should be FALSE. -if child.isalive(): - print 'Child did not exit gracefully.' -else: - print 'Child exited gracefully.' - diff --git a/pexpect/examples/hive.py b/pexpect/examples/hive.py deleted file mode 100755 index b9ef8c1..0000000 --- a/pexpect/examples/hive.py +++ /dev/null @@ -1,468 +0,0 @@ -#!/usr/bin/env python - -'''hive -- Hive Shell - -This lets you ssh to a group of servers and control them as if they were one. -Each command you enter is sent to each host in parallel. The response of each -host is collected and printed. In normal synchronous mode Hive will wait for -each host to return the shell command line prompt. The shell prompt is used to -sync output. - -Example: - - $ hive.py --sameuser --samepass host1.example.com host2.example.net - username: myusername - password: - connecting to host1.example.com - OK - connecting to host2.example.net - OK - targetting hosts: 192.168.1.104 192.168.1.107 - CMD (? for help) > uptime - ======================================================================= - host1.example.com - ----------------------------------------------------------------------- - uptime - 23:49:55 up 74 days, 5:14, 2 users, load average: 0.15, 0.05, 0.01 - ======================================================================= - host2.example.net - ----------------------------------------------------------------------- - uptime - 23:53:02 up 1 day, 13:36, 2 users, load average: 0.50, 0.40, 0.46 - ======================================================================= - -Other Usage Examples: - -1. You will be asked for your username and password for each host. - - hive.py host1 host2 host3 ... hostN - -2. You will be asked once for your username and password. - This will be used for each host. - - hive.py --sameuser --samepass host1 host2 host3 ... hostN - -3. Give a username and password on the command-line: - - hive.py user1:pass2@host1 user2:pass2@host2 ... userN:passN@hostN - -You can use an extended host notation to specify username, password, and host -instead of entering auth information interactively. Where you would enter a -host name use this format: - - username:password@host - -This assumes that ':' is not part of the password. If your password contains a -':' then you can use '\\:' to indicate a ':' and '\\\\' to indicate a single -'\\'. Remember that this information will appear in the process listing. Anyone -on your machine can see this auth information. This is not secure. - -This is a crude script that begs to be multithreaded. But it serves its -purpose. - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -# TODO add feature to support username:password@host combination -# TODO add feature to log each host output in separate file - -import sys -import os -import re -import optparse -import traceback -import types -import time -import getpass -import readline -import atexit -try: - import pexpect - import pxssh -except ImportError: - sys.stderr.write("You do not have 'pexpect' installed.\n") - sys.stderr.write("On Ubuntu you need the 'python-pexpect' package.\n") - sys.stderr.write(" aptitude -y install python-pexpect\n") - exit(1) - -histfile = os.path.join(os.environ["HOME"], ".hive_history") -try: - readline.read_history_file(histfile) -except IOError: - pass -atexit.register(readline.write_history_file, histfile) - -CMD_HELP='''Hive commands are preceded by a colon : (just think of vi). - -:target name1 name2 name3 ... - - set list of hosts to target commands - -:target all - - reset list of hosts to target all hosts in the hive. - -:to name command - - send a command line to the named host. This is similar to :target, but - sends only one command and does not change the list of targets for future - commands. - -:sync - - set mode to wait for shell prompts after commands are run. This is the - default. When Hive first logs into a host it sets a special shell prompt - pattern that it can later look for to synchronize output of the hosts. If - you 'su' to another user then it can upset the synchronization. If you need - to run something like 'su' then use the following pattern: - - CMD (? for help) > :async - CMD (? for help) > sudo su - root - CMD (? for help) > :prompt - CMD (? for help) > :sync - -:async - - set mode to not expect command line prompts (see :sync). Afterwards - commands are send to target hosts, but their responses are not read back - until :sync is run. This is useful to run before commands that will not - return with the special shell prompt pattern that Hive uses to synchronize. - -:refresh - - refresh the display. This shows the last few lines of output from all hosts. - This is similar to resync, but does not expect the promt. This is useful - for seeing what hosts are doing during long running commands. - -:resync - - This is similar to :sync, but it does not change the mode. It looks for the - prompt and thus consumes all input from all targetted hosts. - -:prompt - - force each host to reset command line prompt to the special pattern used to - synchronize all the hosts. This is useful if you 'su' to a different user - where Hive would not know the prompt to match. - -:send my text - - This will send the 'my text' wihtout a line feed to the targetted hosts. - This output of the hosts is not automatically synchronized. - -:control X - - This will send the given control character to the targetted hosts. - For example, ":control c" will send ASCII 3. - -:exit - - This will exit the hive shell. - -''' - -def login (args, cli_username=None, cli_password=None): - - # I have to keep a separate list of host names because Python dicts are not ordered. - # I want to keep the same order as in the args list. - host_names = [] - hive_connect_info = {} - hive = {} - # build up the list of connection information (hostname, username, password, port) - for host_connect_string in args: - hcd = parse_host_connect_string (host_connect_string) - hostname = hcd['hostname'] - port = hcd['port'] - if port == '': - port = None - if len(hcd['username']) > 0: - username = hcd['username'] - elif cli_username is not None: - username = cli_username - else: - username = raw_input('%s username: ' % hostname) - if len(hcd['password']) > 0: - password = hcd['password'] - elif cli_password is not None: - password = cli_password - else: - password = getpass.getpass('%s password: ' % hostname) - host_names.append(hostname) - hive_connect_info[hostname] = (hostname, username, password, port) - # build up the list of hive connections using the connection information. - for hostname in host_names: - print 'connecting to', hostname - try: - fout = file("log_"+hostname, "w") - hive[hostname] = pxssh.pxssh() - # Disable host key checking. - hive[hostname].SSH_OPTS = (hive[hostname].SSH_OPTS - + " -o 'StrictHostKeyChecking=no'" - + " -o 'UserKnownHostsFile /dev/null' ") - hive[hostname].force_password = True - hive[hostname].login(*hive_connect_info[hostname]) - print hive[hostname].before - hive[hostname].logfile = fout - print '- OK' - except Exception, e: - print '- ERROR', - print str(e) - print 'Skipping', hostname - hive[hostname] = None - return host_names, hive - -def main (): - - global options, args, CMD_HELP - - rows = 24 - cols = 80 - - if options.sameuser: - cli_username = raw_input('username: ') - else: - cli_username = None - - if options.samepass: - cli_password = getpass.getpass('password: ') - else: - cli_password = None - - host_names, hive = login(args, cli_username, cli_password) - - synchronous_mode = True - target_hostnames = host_names[:] - print 'targetting hosts:', ' '.join(target_hostnames) - while True: - cmd = raw_input('CMD (? for help) > ') - cmd = cmd.strip() - if cmd=='?' or cmd==':help' or cmd==':h': - print CMD_HELP - continue - elif cmd==':refresh': - refresh (hive, target_hostnames, timeout=0.5) - for hostname in target_hostnames: - print '/' + '=' * (cols - 2) - print '| ' + hostname - print '\\' + '-' * (cols - 2) - if hive[hostname] is None: - print '# DEAD: %s' % hostname - else: - print hive[hostname].before - print '#' * 79 - continue - elif cmd==':resync': - resync (hive, target_hostnames, timeout=0.5) - for hostname in target_hostnames: - print '/' + '=' * (cols - 2) - print '| ' + hostname - print '\\' + '-' * (cols - 2) - if hive[hostname] is None: - print '# DEAD: %s' % hostname - else: - print hive[hostname].before - print '#' * 79 - continue - elif cmd==':sync': - synchronous_mode = True - resync (hive, target_hostnames, timeout=0.5) - continue - elif cmd==':async': - synchronous_mode = False - continue - elif cmd==':prompt': - for hostname in target_hostnames: - try: - if hive[hostname] is not None: - hive[hostname].set_unique_prompt() - except Exception, e: - print "Had trouble communicating with %s, so removing it from the target list." % hostname - print str(e) - hive[hostname] = None - continue - elif cmd[:5] == ':send': - cmd, txt = cmd.split(None,1) - for hostname in target_hostnames: - try: - if hive[hostname] is not None: - hive[hostname].send(txt) - except Exception, e: - print "Had trouble communicating with %s, so removing it from the target list." % hostname - print str(e) - hive[hostname] = None - continue - elif cmd[:3] == ':to': - cmd, hostname, txt = cmd.split(None,2) - print '/' + '=' * (cols - 2) - print '| ' + hostname - print '\\' + '-' * (cols - 2) - if hive[hostname] is None: - print '# DEAD: %s' % hostname - continue - try: - hive[hostname].sendline (txt) - hive[hostname].prompt(timeout=2) - print hive[hostname].before - except Exception, e: - print "Had trouble communicating with %s, so removing it from the target list." % hostname - print str(e) - hive[hostname] = None - continue - elif cmd[:7] == ':expect': - cmd, pattern = cmd.split(None,1) - print 'looking for', pattern - try: - for hostname in target_hostnames: - if hive[hostname] is not None: - hive[hostname].expect(pattern) - print hive[hostname].before - except Exception, e: - print "Had trouble communicating with %s, so removing it from the target list." % hostname - print str(e) - hive[hostname] = None - continue - elif cmd[:7] == ':target': - target_hostnames = cmd.split()[1:] - if len(target_hostnames) == 0 or target_hostnames[0] == all: - target_hostnames = host_names[:] - print 'targetting hosts:', ' '.join(target_hostnames) - continue - elif cmd == ':exit' or cmd == ':q' or cmd == ':quit': - break - elif cmd[:8] == ':control' or cmd[:5] == ':ctrl' : - cmd, c = cmd.split(None,1) - if ord(c)-96 < 0 or ord(c)-96 > 255: - print '/' + '=' * (cols - 2) - print '| Invalid character. Must be [a-zA-Z], @, [, ], \\, ^, _, or ?' - print '\\' + '-' * (cols - 2) - continue - for hostname in target_hostnames: - try: - if hive[hostname] is not None: - hive[hostname].sendcontrol(c) - except Exception, e: - print "Had trouble communicating with %s, so removing it from the target list." % hostname - print str(e) - hive[hostname] = None - continue - elif cmd == ':esc': - for hostname in target_hostnames: - if hive[hostname] is not None: - hive[hostname].send(chr(27)) - continue - # - # Run the command on all targets in parallel - # - for hostname in target_hostnames: - try: - if hive[hostname] is not None: - hive[hostname].sendline (cmd) - except Exception, e: - print "Had trouble communicating with %s, so removing it from the target list." % hostname - print str(e) - hive[hostname] = None - - # - # print the response for each targeted host. - # - if synchronous_mode: - for hostname in target_hostnames: - try: - print '/' + '=' * (cols - 2) - print '| ' + hostname - print '\\' + '-' * (cols - 2) - if hive[hostname] is None: - print '# DEAD: %s' % hostname - else: - hive[hostname].prompt(timeout=2) - print hive[hostname].before - except Exception, e: - print "Had trouble communicating with %s, so removing it from the target list." % hostname - print str(e) - hive[hostname] = None - print '#' * 79 - -def refresh (hive, hive_names, timeout=0.5): - - '''This waits for the TIMEOUT on each host. - ''' - - # TODO This is ideal for threading. - for hostname in hive_names: - if hive[hostname] is not None: - hive[hostname].expect([pexpect.TIMEOUT,pexpect.EOF],timeout=timeout) - -def resync (hive, hive_names, timeout=2, max_attempts=5): - - '''This waits for the shell prompt for each host in an effort to try to get - them all to the same state. The timeout is set low so that hosts that are - already at the prompt will not slow things down too much. If a prompt match - is made for a hosts then keep asking until it stops matching. This is a - best effort to consume all input if it printed more than one prompt. It's - kind of kludgy. Note that this will always introduce a delay equal to the - timeout for each machine. So for 10 machines with a 2 second delay you will - get AT LEAST a 20 second delay if not more. ''' - - # TODO This is ideal for threading. - for hostname in hive_names: - if hive[hostname] is not None: - for attempts in xrange(0, max_attempts): - if not hive[hostname].prompt(timeout=timeout): - break - -def parse_host_connect_string (hcs): - - '''This parses a host connection string in the form - username:password@hostname:port. All fields are options expcet hostname. A - dictionary is returned with all four keys. Keys that were not included are - set to empty strings ''. Note that if your password has the '@' character - then you must backslash escape it. ''' - - if '@' in hcs: - p = re.compile (r'(?P<username>[^@:]*)(:?)(?P<password>.*)(?!\\)@(?P<hostname>[^:]*):?(?P<port>[0-9]*)') - else: - p = re.compile (r'(?P<username>)(?P<password>)(?P<hostname>[^:]*):?(?P<port>[0-9]*)') - m = p.search (hcs) - d = m.groupdict() - d['password'] = d['password'].replace('\\@','@') - return d - -if __name__ == '__main__': - try: - start_time = time.time() - parser = optparse.OptionParser(formatter=optparse.TitledHelpFormatter(), usage=globals()['__doc__'], version='$Id: hive.py 533 2012-10-20 02:19:33Z noah $',conflict_handler="resolve") - parser.add_option ('-v', '--verbose', action='store_true', default=False, help='verbose output') - parser.add_option ('--samepass', action='store_true', default=False, help='Use same password for each login.') - parser.add_option ('--sameuser', action='store_true', default=False, help='Use same username for each login.') - (options, args) = parser.parse_args() - if len(args) < 1: - parser.error ('missing argument') - if options.verbose: print time.asctime() - main() - if options.verbose: print time.asctime() - if options.verbose: print 'TOTAL TIME IN MINUTES:', - if options.verbose: print (time.time() - start_time) / 60.0 - sys.exit(0) - except KeyboardInterrupt, e: # Ctrl-C - raise e - except SystemExit, e: # sys.exit() - raise e - except Exception, e: - print 'ERROR, UNEXPECTED EXCEPTION' - print str(e) - traceback.print_exc() - os._exit(1) diff --git a/pexpect/examples/monitor.py b/pexpect/examples/monitor.py deleted file mode 100755 index b42fc97..0000000 --- a/pexpect/examples/monitor.py +++ /dev/null @@ -1,226 +0,0 @@ -#!/usr/bin/env python - -''' This runs a sequence of commands on a remote host using SSH. It runs a -simple system checks such as uptime and free to monitor the state of the remote -host. - -./monitor.py [-s server_hostname] [-u username] [-p password] - -s : hostname of the remote server to login to. - -u : username to user for login. - -p : Password to user for login. - -Example: - This will print information about the given host: - ./monitor.py -s www.example.com -u mylogin -p mypassword - -It works like this: - Login via SSH (This is the hardest part). - Run and parse 'uptime'. - Run 'iostat'. - Run 'vmstat'. - Run 'netstat' - Run 'free'. - Exit the remote host. - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import os, sys, time, re, getopt, getpass -import traceback -import pexpect - -# -# Some constants. -# -COMMAND_PROMPT = '[#$] ' ### This is way too simple for industrial use -- we will change is ASAP. -TERMINAL_PROMPT = '(?i)terminal type\?' -TERMINAL_TYPE = 'vt100' -# This is the prompt we get if SSH does not have the remote host's public key stored in the cache. -SSH_NEWKEY = '(?i)are you sure you want to continue connecting' - -def exit_with_usage(): - - print globals()['__doc__'] - os._exit(1) - -def main(): - - global COMMAND_PROMPT, TERMINAL_PROMPT, TERMINAL_TYPE, SSH_NEWKEY - ###################################################################### - ## Parse the options, arguments, get ready, etc. - ###################################################################### - try: - optlist, args = getopt.getopt(sys.argv[1:], 'h?s:u:p:', ['help','h','?']) - except Exception, e: - print str(e) - exit_with_usage() - options = dict(optlist) - if len(args) > 1: - exit_with_usage() - - if [elem for elem in options if elem in ['-h','--h','-?','--?','--help']]: - print "Help:" - exit_with_usage() - - if '-s' in options: - host = options['-s'] - else: - host = raw_input('hostname: ') - if '-u' in options: - user = options['-u'] - else: - user = raw_input('username: ') - if '-p' in options: - password = options['-p'] - else: - password = getpass.getpass('password: ') - - # - # Login via SSH - # - child = pexpect.spawn('ssh -l %s %s'%(user, host)) - i = child.expect([pexpect.TIMEOUT, SSH_NEWKEY, COMMAND_PROMPT, '(?i)password']) - if i == 0: # Timeout - print 'ERROR! could not login with SSH. Here is what SSH said:' - print child.before, child.after - print str(child) - sys.exit (1) - if i == 1: # In this case SSH does not have the public key cached. - child.sendline ('yes') - child.expect ('(?i)password') - if i == 2: - # This may happen if a public key was setup to automatically login. - # But beware, the COMMAND_PROMPT at this point is very trivial and - # could be fooled by some output in the MOTD or login message. - pass - if i == 3: - child.sendline(password) - # Now we are either at the command prompt or - # the login process is asking for our terminal type. - i = child.expect ([COMMAND_PROMPT, TERMINAL_PROMPT]) - if i == 1: - child.sendline (TERMINAL_TYPE) - child.expect (COMMAND_PROMPT) - # - # Set command prompt to something more unique. - # - COMMAND_PROMPT = "\[PEXPECT\]\$ " - child.sendline ("PS1='[PEXPECT]\$ '") # In case of sh-style - i = child.expect ([pexpect.TIMEOUT, COMMAND_PROMPT], timeout=10) - if i == 0: - print "# Couldn't set sh-style prompt -- trying csh-style." - child.sendline ("set prompt='[PEXPECT]\$ '") - i = child.expect ([pexpect.TIMEOUT, COMMAND_PROMPT], timeout=10) - if i == 0: - print "Failed to set command prompt using sh or csh style." - print "Response was:" - print child.before - sys.exit (1) - - # Now we should be at the command prompt and ready to run some commands. - print '---------------------------------------' - print 'Report of commands run on remote host.' - print '---------------------------------------' - - # Run uname. - child.sendline ('uname -a') - child.expect (COMMAND_PROMPT) - print child.before - if 'linux' in child.before.lower(): - LINUX_MODE = 1 - else: - LINUX_MODE = 0 - - # Run and parse 'uptime'. - child.sendline ('uptime') - child.expect('up\s+(.*?),\s+([0-9]+) users?,\s+load averages?: ([0-9]+\.[0-9][0-9]),?\s+([0-9]+\.[0-9][0-9]),?\s+([0-9]+\.[0-9][0-9])') - duration, users, av1, av5, av15 = child.match.groups() - days = '0' - hours = '0' - mins = '0' - if 'day' in duration: - child.match = re.search('([0-9]+)\s+day',duration) - days = str(int(child.match.group(1))) - if ':' in duration: - child.match = re.search('([0-9]+):([0-9]+)',duration) - hours = str(int(child.match.group(1))) - mins = str(int(child.match.group(2))) - if 'min' in duration: - child.match = re.search('([0-9]+)\s+min',duration) - mins = str(int(child.match.group(1))) - print - print 'Uptime: %s days, %s users, %s (1 min), %s (5 min), %s (15 min)' % ( - duration, users, av1, av5, av15) - child.expect (COMMAND_PROMPT) - - # Run iostat. - child.sendline ('iostat') - child.expect (COMMAND_PROMPT) - print child.before - - # Run vmstat. - child.sendline ('vmstat') - child.expect (COMMAND_PROMPT) - print child.before - - # Run free. - if LINUX_MODE: - child.sendline ('free') # Linux systems only. - child.expect (COMMAND_PROMPT) - print child.before - - # Run df. - child.sendline ('df') - child.expect (COMMAND_PROMPT) - print child.before - - # Run lsof. - child.sendline ('lsof') - child.expect (COMMAND_PROMPT) - print child.before - -# # Run netstat -# child.sendline ('netstat') -# child.expect (COMMAND_PROMPT) -# print child.before - -# # Run MySQL show status. -# child.sendline ('mysql -p -e "SHOW STATUS;"') -# child.expect (PASSWORD_PROMPT_MYSQL) -# child.sendline (password_mysql) -# child.expect (COMMAND_PROMPT) -# print -# print child.before - - # Now exit the remote host. - child.sendline ('exit') - index = child.expect([pexpect.EOF, "(?i)there are stopped jobs"]) - if index==1: - child.sendline("exit") - child.expect(EOF) - -if __name__ == "__main__": - - try: - main() - except Exception, e: - print str(e) - traceback.print_exc() - os._exit(1) - diff --git a/pexpect/examples/passmass.py b/pexpect/examples/passmass.py deleted file mode 100755 index 1e371a4..0000000 --- a/pexpect/examples/passmass.py +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/env python - -'''Change passwords on the named machines. passmass host1 host2 host3 . . . -Note that login shell prompt on remote machine must end in # or $. - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import pexpect -import sys, getpass - -USAGE = '''passmass host1 host2 host3 . . .''' -COMMAND_PROMPT = '[$#] ' -TERMINAL_PROMPT = r'Terminal type\?' -TERMINAL_TYPE = 'vt100' -SSH_NEWKEY = r'Are you sure you want to continue connecting \(yes/no\)\?' - -def login(host, user, password): - - child = pexpect.spawn('ssh -l %s %s'%(user, host)) - fout = file ("LOG.TXT","wb") - child.setlog (fout) - - i = child.expect([pexpect.TIMEOUT, SSH_NEWKEY, '[Pp]assword: ']) - if i == 0: # Timeout - print 'ERROR!' - print 'SSH could not login. Here is what SSH said:' - print child.before, child.after - sys.exit (1) - if i == 1: # SSH does not have the public key. Just accept it. - child.sendline ('yes') - child.expect ('[Pp]assword: ') - child.sendline(password) - # Now we are either at the command prompt or - # the login process is asking for our terminal type. - i = child.expect (['Permission denied', TERMINAL_PROMPT, COMMAND_PROMPT]) - if i == 0: - print 'Permission denied on host:', host - sys.exit (1) - if i == 1: - child.sendline (TERMINAL_TYPE) - child.expect (COMMAND_PROMPT) - return child - -# (current) UNIX password: -def change_password(child, user, oldpassword, newpassword): - - child.sendline('passwd') - i = child.expect(['[Oo]ld [Pp]assword', '.current.*password', '[Nn]ew [Pp]assword']) - # Root does not require old password, so it gets to bypass the next step. - if i == 0 or i == 1: - child.sendline(oldpassword) - child.expect('[Nn]ew [Pp]assword') - child.sendline(newpassword) - i = child.expect(['[Nn]ew [Pp]assword', '[Rr]etype', '[Rr]e-enter']) - if i == 0: - print 'Host did not like new password. Here is what it said...' - print child.before - child.send (chr(3)) # Ctrl-C - child.sendline('') # This should tell remote passwd command to quit. - return - child.sendline(newpassword) - -def main(): - - if len(sys.argv) <= 1: - print USAGE - return 1 - - user = raw_input('Username: ') - password = getpass.getpass('Current Password: ') - newpassword = getpass.getpass('New Password: ') - newpasswordconfirm = getpass.getpass('Confirm New Password: ') - if newpassword != newpasswordconfirm: - print 'New Passwords do not match.' - return 1 - - for host in sys.argv[1:]: - child = login(host, user, password) - if child == None: - print 'Could not login to host:', host - continue - print 'Changing password on host:', host - change_password(child, user, password, newpassword) - child.expect(COMMAND_PROMPT) - child.sendline('exit') - -if __name__ == '__main__': - try: - main() - except pexpect.ExceptionPexpect, e: - print str(e) - diff --git a/pexpect/examples/python.py b/pexpect/examples/python.py deleted file mode 100755 index c095bec..0000000 --- a/pexpect/examples/python.py +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env python - -'''This starts the python interpreter; captures the startup message; then gives -the user interactive control over the session. Why? For fun... - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -# Don't do this unless you like being John Malkovich -# c = pexpect.spawn ('/usr/bin/env python ./python.py') - -import pexpect -c = pexpect.spawn ('/usr/bin/env python') -c.expect ('>>>') -print 'And now for something completely different...' -f = lambda s:s and f(s[1:])+s[0] # Makes a function to reverse a string. -print f(c.before) -print 'Yes, it\'s python, but it\'s backwards.' -print -print 'Escape character is \'^]\'.' -print c.after, -c.interact() -c.kill(1) -print 'is alive:', c.isalive() - diff --git a/pexpect/examples/rippy.py b/pexpect/examples/rippy.py deleted file mode 100755 index 25e23e0..0000000 --- a/pexpect/examples/rippy.py +++ /dev/null @@ -1,988 +0,0 @@ -#!/usr/bin/env python - -'''Rippy! - -This is old and probably does not work anymore. -This script helps to convert video from one format to another. -This is useful for ripping DVD to mpeg4 video (XviD, DivX). - -Features: - * automatic crop detection - * mp3 audio compression with resampling options - * automatic bitrate calculation based on desired target size - * optional interlace removal, b/w video optimization, video scaling - -Run the script with no arguments to start with interactive prompts: - rippy.py -Run the script with the filename of a config to start automatic mode: - rippy.py rippy.conf - -After Rippy is finished it saves the current configuation in a file called -'rippy.conf' in the local directoy. This can be used to rerun process using the -exact same settings by passing the filename of the conf file as an argument to -Rippy. Rippy will read the options from the file instead of asking you for -options interactively. So if you run rippy with 'dry_run=1' then you can run -the process again later using the 'rippy.conf' file. Don't forget to edit -'rippy.conf' to set 'dry_run=0'! - -If you run rippy with 'dry_run' and 'verbose' true then the output generated is -valid command line commands. you could (in theory) cut-and-paste the commands -to a shell prompt. You will need to tweak some values such as crop area and bit -rate because these cannot be calculated in a dry run. This is useful if you -want to get an idea of what Rippy plans to do. - -For all the trouble that Rippy goes through to calculate the best bitrate for a -desired target video size it sometimes fails to get it right. Sometimes the -final video size will differ more than you wanted from the desired size, but if -you are really motivated and have a lot of time on your hands then you can run -Rippy again with a manually calculated bitrate. After all compression is done -the first time Rippy will recalculate the bitrate to give you the nearly exact -bitrate that would have worked. You can then edit the 'rippy.conf' file; set -the video_bitrate with this revised bitrate; and then run Rippy all over again. -There is nothing like 4-pass video compression to get it right! Actually, this -could be done in three passes since I don't need to do the second pass -compression before I calculate the revised bitrate. I'm also considering an -enhancement where Rippy would compress ten spread out chunks, 1-minute in -length to estimate the bitrate. - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import sys, os, re, math, stat, getopt, traceback, types, time -import pexpect - -__version__ = '1.2' -__revision__ = '$Revision: 11 $' -__all__ = ['main', __version__, __revision__] - -GLOBAL_LOGFILE_NAME = "rippy_%d.log" % os.getpid() -GLOBAL_LOGFILE = open (GLOBAL_LOGFILE_NAME, "wb") - -############################################################################### -# This giant section defines the prompts and defaults used in interactive mode. -############################################################################### -# Python dictionaries are unordered, so -# I have this list that maintains the order of the keys. -prompts_key_order = ( -'verbose_flag', -'dry_run_flag', -'video_source_filename', -'video_chapter', -'video_final_filename', -'video_length', -'video_aspect_ratio', -'video_scale', -'video_encode_passes', -'video_codec', -'video_fourcc_override', -'video_bitrate', -'video_bitrate_overhead', -'video_target_size', -'video_deinterlace_flag', -'video_crop_area', -'video_gray_flag', -'subtitle_id', -'audio_id', -'audio_codec', -'audio_raw_filename', -'audio_volume_boost', -'audio_sample_rate', -'audio_bitrate', -#'audio_lowpass_filter', -'delete_tmp_files_flag' -) -# -# The 'prompts' dictionary holds all the messages shown to the user in -# interactive mode. The 'prompts' dictionary schema is defined as follows: -# prompt_key : ( default value, prompt string, help string, level of difficulty (0,1,2) ) -# -prompts = { -'video_source_filename':("dvd://1", 'video source filename?', '''This is the filename of the video that you want to convert from. -It can be any file that mencoder supports. -You can also choose a DVD device using the dvd://1 syntax. -Title 1 is usually the main title on a DVD.''',0), -'video_chapter':("none",'video chapter?','''This is the chapter number. Usually disks such as TV series seasons will be divided into chapters. Maybe be set to none.''',0), -'video_final_filename':("video_final.avi", "video final filename?", '''This is the name of the final video.''',0), -'audio_raw_filename':("audiodump.wav", "audio raw filename?", '''This is the audio raw PCM filename. This is prior to compression. -Note that mplayer automatically names this audiodump.wav, so don't change this.''',1000), -#'audio_compressed_filename':("audiodump.mp3","Audio compressed filename?", '''This is the name of the compressed audio that will be mixed -#into the final video. Normally you don't need to change this.''',2), -'video_length':("none","video length in seconds?",'''This sets the length of the video in seconds. This is used to estimate the -bitrate for a target video file size. Set to 'calc' to have Rippy calculate -the length. Set to 'none' if you don't want rippy to estimate the bitrate -- -you will have to manually specify bitrate.''',1), -'video_aspect_ratio':("calc","aspect ratio?",'''This sets the aspect ratio of the video. Most DVDs are 16/9 or 4/3.''',1), -'video_scale':("none","video scale?",'''This scales the video to the given output size. The default is to do no scaling. -You may type in a resolution such as 320x240 or you may use presets. - qntsc: 352x240 (NTSC quarter screen) - qpal: 352x288 (PAL quarter screen) - ntsc: 720x480 (standard NTSC) - pal: 720x576 (standard PAL) - sntsc: 640x480 (square pixel NTSC) - spal: 768x576 (square pixel PAL)''',1), -'video_codec':("mpeg4","video codec?",'''This is the video compression to use. This is passed directly to mencoder, so -any format that it recognizes should work. For XviD or DivX use mpeg4. -Almost all MS Windows systems support wmv2 out of the box. -Some common codecs include: -mjpeg, h263, h263p, h264, mpeg4, msmpeg4, wmv1, wmv2, mpeg1video, mpeg2video, huffyuv, ffv1. -''',2), -'audio_codec':("mp3","audio codec?",'''This is the audio compression to use. This is passed directly to mencoder, so -any format that it recognizes will work. -Some common codecs include: -mp3, mp2, aac, pcm -See mencoder manual for details.''',2), -'video_fourcc_override':("XVID","force fourcc code?",'''This forces the fourcc codec to the given value. XVID is safest for Windows. -The following are common fourcc values: - FMP4 - This is the mencoder default. This is the "real" value. - XVID - used by Xvid (safest) - DX50 - - MP4S - Microsoft''',2), -'video_encode_passes':("1","number of encode passes?",'''This sets how many passes to use to encode the video. You can choose 1 or 2. -Using two pases takes twice as long as one pass, but produces a better -quality video. I found that the improvement is not that impressive.''',1), -'verbose_flag':("Y","verbose output?",'''This sets verbose output. If true then all commands and arguments are printed -before they are run. This is useful to see exactly how commands are run.''',1), -'dry_run_flag':("N","dry run?",'''This sets 'dry run' mode. If true then commands are not run. This is useful -if you want to see what would the script would do.''',1), -'video_bitrate':("calc","video bitrate?",'''This sets the video bitrate. This overrides video_target_size. -Set to 'calc' to automatically estimate the bitrate based on the -video final target size. If you set video_length to 'none' then -you will have to specify this video_bitrate.''',1), -'video_target_size':("737280000","video final target size?",'''This sets the target video size that you want to end up with. -This is over-ridden by video_bitrate. In other words, if you specify -video_bitrate then video_target_size is ignored. -Due to the unpredictable nature of VBR compression the final video size -may not exactly match. The following are common CDR sizes: - 180MB CDR (21 minutes) holds 193536000 bytes - 550MB CDR (63 minutes) holds 580608000 bytes - 650MB CDR (74 minutes) holds 681984000 bytes - 700MB CDR (80 minutes) holds 737280000 bytes''',0), -'video_bitrate_overhead':("1.0","bitrate overhead factor?",'''Adjust this value if you want to leave more room for -other files such as subtitle files. -If you specify video_bitrate then this value is ignored.''',2), -'video_crop_area':("detect","crop area?",'''This sets the crop area to remove black bars from the top or sides of the video. -This helps save space. Set to 'detect' to automatically detect the crop area. -Set to 'none' to not crop the video. Normally you don't need to change this.''',1), -'video_deinterlace_flag':("N","is the video interlaced?",'''This sets the deinterlace flag. If set then mencoder will be instructed -to filter out interlace artifacts (using '-vf pp=md').''',1), -'video_gray_flag':("N","is the video black and white (gray)?",'''This improves output for black and white video.''',1), -'subtitle_id':("None","Subtitle ID stream?",'''This selects the subtitle stream to extract from the source video. -Normally, 0 is the English subtitle stream for a DVD. -Subtitles IDs with higher numbers may be other languages.''',1), -'audio_id':("128","audio ID stream?",'''This selects the audio stream to extract from the source video. -If your source is a VOB file (DVD) then stream IDs start at 128. -Normally, 128 is the main audio track for a DVD. -Tracks with higher numbers may be other language dubs or audio commentary.''',1), -'audio_sample_rate':("32000","audio sample rate (Hz) 48000, 44100, 32000, 24000, 12000",'''This sets the rate at which the compressed audio will be resampled. -DVD audio is 48 kHz whereas music CDs use 44.1 kHz. The higher the sample rate -the more space the audio track will take. That will leave less space for video. -32 kHz is a good trade-off if you are trying to fit a video onto a CD.''',1), -'audio_bitrate':("96","audio bitrate (kbit/s) 192, 128, 96, 64?",'''This sets the bitrate for MP3 audio compression. -The higher the bitrate the more space the audio track will take. -That will leave less space for video. Most people find music to be acceptable -at 128 kBitS. 96 kBitS is a good trade-off if you are trying to fit a video onto a CD.''',1), -'audio_volume_boost':("none","volume dB boost?",'''Many DVDs have very low audio volume. This sets an audio volume boost in Decibels. -Values of 6 to 10 usually adjust quiet DVDs to a comfortable level.''',1), -#'audio_lowpass_filter':("16","audio lowpass filter (kHz)?",'''This sets the low-pass filter for the audio. -#Normally this should be half of the audio sample rate. -#This improves audio compression and quality. -#Normally you don't need to change this.''',1), -'delete_tmp_files_flag':("N","delete temporary files when finished?",'''If Y then %s, audio_raw_filename, and 'divx2pass.log' will be deleted at the end.'''%GLOBAL_LOGFILE_NAME,1) -} - -############################################################################## -# This is the important convert control function -############################################################################## -def convert (options): - '''This is the heart of it all -- this performs an end-to-end conversion of - a video from one format to another. It requires a dictionary of options. - The conversion process will also add some keys to the dictionary - such as length of the video and crop area. The dictionary is returned. - This options dictionary could be used again to repeat the convert process - (it is also saved to rippy.conf as text). - ''' - if options['subtitle_id'] is not None: - print "# extract subtitles" - apply_smart (extract_subtitles, options) - else: - print "# do not extract subtitles." - - # Optimization - # I really only need to calculate the exact video length if the user - # selected 'calc' for video_bitrate - # or - # selected 'detect' for video_crop_area. - if options['video_bitrate']=='calc' or options['video_crop_area']=='detect': - # As strange as it seems, the only reliable way to calculate the length - # of a video (in seconds) is to extract the raw, uncompressed PCM audio stream - # and then calculate the length of that. This is because MP4 video is VBR, so - # you cannot get exact time based on compressed size. - if options['video_length']=='calc': - print "# extract PCM raw audio to %s" % (options['audio_raw_filename']) - apply_smart (extract_audio, options) - options['video_length'] = apply_smart (get_length, options) - print "# Length of raw audio file : %d seconds (%0.2f minutes)" % (options['video_length'], float(options['video_length'])/60.0) - if options['video_bitrate']=='calc': - options['video_bitrate'] = options['video_bitrate_overhead'] * apply_smart (calc_video_bitrate, options) - print "# video bitrate : " + str(options['video_bitrate']) - if options['video_crop_area']=='detect': - options['video_crop_area'] = apply_smart (crop_detect, options) - print "# crop area : " + str(options['video_crop_area']) - print "# compression estimate" - print apply_smart (compression_estimate, options) - - print "# compress video" - apply_smart (compress_video, options) - 'audio_volume_boost', - - print "# delete temporary files:", - if options['delete_tmp_files_flag']: - print "yes" - apply_smart (delete_tmp_files, options) - else: - print "no" - - # Finish by saving options to rippy.conf and - # calclating if final_size is less than target_size. - o = ["# options used to create video\n"] - video_actual_size = get_filesize (options['video_final_filename']) - if options['video_target_size'] != 'none': - revised_bitrate = calculate_revised_bitrate (options['video_bitrate'], options['video_target_size'], video_actual_size) - o.append("# revised video_bitrate : %d\n" % revised_bitrate) - for k,v in options.iteritems(): - o.append (" %30s : %s\n" % (k, v)) - print '# '.join(o) - fout = open("rippy.conf","wb").write(''.join(o)) - print "# final actual video size = %d" % video_actual_size - if options['video_target_size'] != 'none': - if video_actual_size > options['video_target_size']: - print "# FINAL VIDEO SIZE IS GREATER THAN DESIRED TARGET" - print "# final video size is %d bytes over target size" % (video_actual_size - options['video_target_size']) - else: - print "# final video size is %d bytes under target size" % (options['video_target_size'] - video_actual_size) - print "# If you want to run the entire compression process all over again" - print "# to get closer to the target video size then trying using a revised" - print "# video_bitrate of %d" % revised_bitrate - - return options - -############################################################################## - -def exit_with_usage(exit_code=1): - print globals()['__doc__'] - print 'version:', globals()['__version__'] - sys.stdout.flush() - os._exit(exit_code) - -def check_missing_requirements (): - '''This list of missing requirements (mencoder, mplayer, lame, and mkvmerge). - Returns None if all requirements are in the execution path. - ''' - missing = [] - if pexpect.which("mencoder") is None: - missing.append("mencoder") - if pexpect.which("mplayer") is None: - missing.append("mplayer") - cmd = "mencoder -oac help" - (command_output, exitstatus) = run(cmd) - ar = re.findall("(mp3lame)", command_output) - if len(ar)==0: - missing.append("Mencoder was not compiled with mp3lame support.") - - #if pexpect.which("lame") is None: - # missing.append("lame") - #if pexpect.which("mkvmerge") is None: - # missing.append("mkvmerge") - if len(missing)==0: - return None - return missing - -def input_option (message, default_value="", help=None, level=0, max_level=0): - '''This is a fancy raw_input function. - If the user enters '?' then the contents of help is printed. - - The 'level' and 'max_level' are used to adjust which advanced options - are printed. 'max_level' is the level of options that the user wants - to see. 'level' is the level of difficulty for this particular option. - If this level is <= the max_level the user wants then the - message is printed and user input is allowed; otherwise, the - default value is returned automatically without user input. - ''' - if default_value != '': - message = "%s [%s] " % (message, default_value) - if level > max_level: - return default_value - while 1: - user_input = raw_input (message) - if user_input=='?': - print help - elif user_input=='': - return default_value - else: - break - return user_input - -def progress_callback (d=None): - '''This callback simply prints a dot to show activity. - This is used when running external commands with pexpect.run. - ''' - sys.stdout.write (".") - sys.stdout.flush() - -def run(cmd): - global GLOBAL_LOGFILE - print >>GLOBAL_LOGFILE, cmd - (command_output, exitstatus) = pexpect.run(cmd, events={pexpect.TIMEOUT:progress_callback}, timeout=5, withexitstatus=True, logfile=GLOBAL_LOGFILE) - if exitstatus != 0: - print "RUN FAILED. RETURNED EXIT STATUS:", exitstatus - print >>GLOBAL_LOGFILE, "RUN FAILED. RETURNED EXIT STATUS:", exitstatus - return (command_output, exitstatus) - -def apply_smart (func, args): - '''This is similar to func(**args), but this won't complain about - extra keys in 'args'. This ignores keys in 'args' that are - not required by 'func'. This passes None to arguments that are - not defined in 'args'. That's fine for arguments with a default valeue, but - that's a bug for required arguments. I should probably raise a TypeError. - The func parameter can be a function reference or a string. - If it is a string then it is converted to a function reference. - ''' - if type(func) is type(''): - if func in globals(): - func = globals()[func] - else: - raise NameError("name '%s' is not defined" % func) - if hasattr(func,'im_func'): # Handle case when func is a class method. - func = func.im_func - argcount = func.func_code.co_argcount - required_args = dict([(k,args.get(k)) for k in func.func_code.co_varnames[:argcount]]) - return func(**required_args) - -def count_unique (items): - '''This takes a list and returns a sorted list of tuples with a count of each unique item in the list. - Example 1: - count_unique(['a','b','c','a','c','c','a','c','c']) - returns: - [(5,'c'), (3,'a'), (1,'b')] - Example 2 -- get the most frequent item in a list: - count_unique(['a','b','c','a','c','c','a','c','c'])[0][1] - returns: - 'c' - ''' - stats = {} - for i in items: - if i in stats: - stats[i] = stats[i] + 1 - else: - stats[i] = 1 - stats = [(v, k) for k, v in stats.items()] - stats.sort() - stats.reverse() - return stats - -def calculate_revised_bitrate (video_bitrate, video_target_size, video_actual_size): - '''This calculates a revised video bitrate given the video_bitrate used, - the actual size that resulted, and the video_target_size. - This can be used if you want to compress the video all over again in an - attempt to get closer to the video_target_size. - ''' - return int(math.floor(video_bitrate * (float(video_target_size) / float(video_actual_size)))) - -def get_aspect_ratio (video_source_filename): - '''This returns the aspect ratio of the original video. - This is usualy 1.78:1(16/9) or 1.33:1(4/3). - This function is very lenient. It basically guesses 16/9 whenever - it cannot figure out the aspect ratio. - ''' - cmd = "mplayer '%s' -vo png -ao null -frames 1" % video_source_filename - (command_output, exitstatus) = run(cmd) - ar = re.findall("Movie-Aspect is ([0-9]+\.?[0-9]*:[0-9]+\.?[0-9]*)", command_output) - if len(ar)==0: - return '16/9' - if ar[0] == '1.78:1': - return '16/9' - if ar[0] == '1.33:1': - return '4/3' - return '16/9' - #idh = re.findall("ID_VIDEO_HEIGHT=([0-9]+)", command_output) - #if len(idw)==0 or len(idh)==0: - # print 'WARNING!' - # print 'Could not get aspect ration. Assuming 1.78:1 (16/9).' - # return 1.78 - #return float(idw[0])/float(idh[0]) -#ID_VIDEO_WIDTH=720 -#ID_VIDEO_HEIGHT=480 -#Movie-Aspect is 1.78:1 - prescaling to correct movie aspect. - - -def get_aid_list (video_source_filename): - '''This returns a list of audio ids in the source video file. - TODO: Also extract ID_AID_nnn_LANG to associate language. Not all DVDs include this. - ''' - cmd = "mplayer '%s' -vo null -ao null -frames 0 -identify" % video_source_filename - (command_output, exitstatus) = run(cmd) - idl = re.findall("ID_AUDIO_ID=([0-9]+)", command_output) - idl.sort() - return idl - -def get_sid_list (video_source_filename): - '''This returns a list of subtitle ids in the source video file. - TODO: Also extract ID_SID_nnn_LANG to associate language. Not all DVDs include this. - ''' - cmd = "mplayer '%s' -vo null -ao null -frames 0 -identify" % video_source_filename - (command_output, exitstatus) = run(cmd) - idl = re.findall("ID_SUBTITLE_ID=([0-9]+)", command_output) - idl.sort() - return idl - -def extract_audio (video_source_filename, audio_id=128, verbose_flag=0, dry_run_flag=0): - '''This extracts the given audio_id track as raw uncompressed PCM from the given source video. - Note that mplayer always saves this to audiodump.wav. - At this time there is no way to set the output audio name. - ''' - #cmd = "mplayer %(video_source_filename)s -vc null -vo null -aid %(audio_id)s -ao pcm:fast -noframedrop" % locals() - cmd = "mplayer -quiet '%(video_source_filename)s' -vc dummy -vo null -aid %(audio_id)s -ao pcm:fast -noframedrop" % locals() - if verbose_flag: print cmd - if not dry_run_flag: - run(cmd) - print - -def extract_subtitles (video_source_filename, subtitle_id=0, verbose_flag=0, dry_run_flag=0): - '''This extracts the given subtitle_id track as VOBSUB format from the given source video. - ''' - cmd = "mencoder -quiet '%(video_source_filename)s' -o /dev/null -nosound -ovc copy -vobsubout subtitles -vobsuboutindex 0 -sid %(subtitle_id)s" % locals() - if verbose_flag: print cmd - if not dry_run_flag: - run(cmd) - print - -def get_length (audio_raw_filename): - '''This attempts to get the length of the media file (length is time in seconds). - This should not be confused with size (in bytes) of the file data. - This is best used on a raw PCM AUDIO file because mplayer cannot get an accurate - time for many compressed video and audio formats -- notably MPEG4 and MP3. - Weird... - This returns -1 if it cannot get the length of the given file. - ''' - cmd = "mplayer %s -vo null -ao null -frames 0 -identify" % audio_raw_filename - (command_output, exitstatus) = run(cmd) - idl = re.findall("ID_LENGTH=([0-9.]*)", command_output) - idl.sort() - if len(idl) != 1: - print "ERROR: cannot get length of raw audio file." - print "command_output of mplayer identify:" - print command_output - print "parsed command_output:" - print str(idl) - return -1 - return float(idl[0]) - -def get_filesize (filename): - '''This returns the number of bytes a file takes on storage.''' - return os.stat(filename)[stat.ST_SIZE] - -def calc_video_bitrate (video_target_size, audio_bitrate, video_length, extra_space=0, dry_run_flag=0): - '''This gives an estimate of the video bitrate necessary to - fit the final target size. This will take into account room to - fit the audio and extra space if given (for container overhead or whatnot). - video_target_size is in bytes, - audio_bitrate is bits per second (96, 128, 256, etc.) ASSUMING CBR, - video_length is in seconds, - extra_space is in bytes. - a 180MB CDR (21 minutes) holds 193536000 bytes. - a 550MB CDR (63 minutes) holds 580608000 bytes. - a 650MB CDR (74 minutes) holds 681984000 bytes. - a 700MB CDR (80 minutes) holds 737280000 bytes. - ''' - if dry_run_flag: - return -1 - if extra_space is None: extra_space = 0 - #audio_size = os.stat(audio_compressed_filename)[stat.ST_SIZE] - audio_size = (audio_bitrate * video_length * 1000) / 8.0 - video_target_size = video_target_size - audio_size - extra_space - return (int)(calc_video_kbitrate (video_target_size, video_length)) - -def calc_video_kbitrate (target_size, length_secs): - '''Given a target byte size free for video data, this returns the bitrate in kBit/S. - For mencoder vbitrate 1 kBit = 1000 Bits -- not 1024 bits. - target_size = bitrate * 1000 * length_secs / 8 - target_size = bitrate * 125 * length_secs - bitrate = target_size/(125*length_secs) - ''' - return int(target_size / (125.0 * length_secs)) - -def crop_detect (video_source_filename, video_length, dry_run_flag=0): - '''This attempts to figure out the best crop for the given video file. - Basically it runs crop detect for 10 seconds on five different places in the video. - It picks the crop area that was most often detected. - ''' - skip = int(video_length/9) # offset to skip (-ss option in mencoder) - sample_length = 10 - cmd1 = "mencoder '%s' -quiet -ss %d -endpos %d -o /dev/null -nosound -ovc lavc -vf cropdetect" % (video_source_filename, skip, sample_length) - cmd2 = "mencoder '%s' -quiet -ss %d -endpos %d -o /dev/null -nosound -ovc lavc -vf cropdetect" % (video_source_filename, 2*skip, sample_length) - cmd3 = "mencoder '%s' -quiet -ss %d -endpos %d -o /dev/null -nosound -ovc lavc -vf cropdetect" % (video_source_filename, 4*skip, sample_length) - cmd4 = "mencoder '%s' -quiet -ss %d -endpos %d -o /dev/null -nosound -ovc lavc -vf cropdetect" % (video_source_filename, 6*skip, sample_length) - cmd5 = "mencoder '%s' -quiet -ss %d -endpos %d -o /dev/null -nosound -ovc lavc -vf cropdetect" % (video_source_filename, 8*skip, sample_length) - if dry_run_flag: - return "0:0:0:0" - (command_output1, exitstatus1) = run(cmd1) - (command_output2, exitstatus2) = run(cmd2) - (command_output3, exitstatus3) = run(cmd3) - (command_output4, exitstatus4) = run(cmd4) - (command_output5, exitstatus5) = run(cmd5) - idl = re.findall("-vf crop=([0-9]+:[0-9]+:[0-9]+:[0-9]+)", command_output1) - idl = idl + re.findall("-vf crop=([0-9]+:[0-9]+:[0-9]+:[0-9]+)", command_output2) - idl = idl + re.findall("-vf crop=([0-9]+:[0-9]+:[0-9]+:[0-9]+)", command_output3) - idl = idl + re.findall("-vf crop=([0-9]+:[0-9]+:[0-9]+:[0-9]+)", command_output4) - idl = idl + re.findall("-vf crop=([0-9]+:[0-9]+:[0-9]+:[0-9]+)", command_output5) - items_count = count_unique(idl) - return items_count[0][1] - - -def build_compression_command (video_source_filename, video_final_filename, video_target_size, audio_id=128, video_bitrate=1000, video_codec='mpeg4', audio_codec='mp3', video_fourcc_override='FMP4', video_gray_flag=0, video_crop_area=None, video_aspect_ratio='16/9', video_scale=None, video_encode_passes=2, video_deinterlace_flag=0, audio_volume_boost=None, audio_sample_rate=None, audio_bitrate=None, seek_skip=None, seek_length=None, video_chapter=None): -#Notes:For DVD, VCD, and SVCD use acodec=mp2 and vcodec=mpeg2video: -#mencoder movie.avi -o movie.VOB -ovc lavc -oac lavc -lavcopts acodec=mp2:abitrate=224:vcodec=mpeg2video:vbitrate=2000 - - # - # build video filter (-vf) argument - # - video_filter = '' - if video_crop_area and video_crop_area.lower()!='none': - video_filter = video_filter + 'crop=%s' % video_crop_area - if video_deinterlace_flag: - if video_filter != '': - video_filter = video_filter + ',' - video_filter = video_filter + 'pp=md' - if video_scale and video_scale.lower()!='none': - if video_filter != '': - video_filter = video_filter + ',' - video_filter = video_filter + 'scale=%s' % video_scale - # optional video rotation -- were you holding your camera sideways? - #if video_filter != '': - # video_filter = video_filter + ',' - #video_filter = video_filter + 'rotate=2' - if video_filter != '': - video_filter = '-vf ' + video_filter - - # - # build chapter argument - # - if video_chapter is not None: - chapter = '-chapter %d-%d' %(video_chapter,video_chapter) - else: - chapter = '' -# chapter = '-chapter 2-2' - - # - # build audio_filter argument - # - audio_filter = '' - if audio_sample_rate: - if audio_filter != '': - audio_filter = audio_filter + ',' - audio_filter = audio_filter + 'lavcresample=%s' % audio_sample_rate - if audio_volume_boost is not None: - if audio_filter != '': - audio_filter = audio_filter + ',' - audio_filter = audio_filter + 'volume=%0.1f:1'%audio_volume_boost - if audio_filter != '': - audio_filter = '-af ' + audio_filter - # - #if audio_sample_rate: - # audio_filter = ('-srate %d ' % audio_sample_rate) + audio_filter - - # - # build lavcopts argument - # - #lavcopts = '-lavcopts vcodec=%s:vbitrate=%d:mbd=2:aspect=%s:acodec=%s:abitrate=%d:vpass=1' % (video_codec,video_bitrate,audio_codec,audio_bitrate) - lavcopts = '-lavcopts vcodec=%(video_codec)s:vbitrate=%(video_bitrate)d:mbd=2:aspect=%(video_aspect_ratio)s:acodec=%(audio_codec)s:abitrate=%(audio_bitrate)d:vpass=1' % (locals()) - if video_gray_flag: - lavcopts = lavcopts + ':gray' - - seek_filter = '' - if seek_skip is not None: - seek_filter = '-ss %s' % (str(seek_skip)) - if seek_length is not None: - seek_filter = seek_filter + ' -endpos %s' % (str(seek_length)) - -# cmd = "mencoder -quiet -info comment='Arkivist' '%(video_source_filename)s' %(seek_filter)s %(chapter)s -aid %(audio_id)s -o '%(video_final_filename)s' -ffourcc %(video_fourcc_override)s -ovc lavc -oac lavc %(lavcopts)s %(video_filter)s %(audio_filter)s" % locals() - cmd = "mencoder -quiet -info comment='Arkivist' '%(video_source_filename)s' %(seek_filter)s %(chapter)s -aid %(audio_id)s -o '%(video_final_filename)s' -ffourcc %(video_fourcc_override)s -ovc lavc -oac mp3lame %(lavcopts)s %(video_filter)s %(audio_filter)s" % locals() - return cmd - -def compression_estimate (video_length, video_source_filename, video_final_filename, video_target_size, audio_id=128, video_bitrate=1000, video_codec='mpeg4', audio_codec='mp3', video_fourcc_override='FMP4', video_gray_flag=0, video_crop_area=None, video_aspect_ratio='16/9', video_scale=None, video_encode_passes=2, video_deinterlace_flag=0, audio_volume_boost=None, audio_sample_rate=None, audio_bitrate=None): - '''This attempts to figure out the best compression ratio for a given set of compression options. - ''' - # TODO Need to account for AVI overhead. - skip = int(video_length/9) # offset to skip (-ss option in mencoder) - sample_length = 10 - cmd1 = build_compression_command (video_source_filename, "compression_test_1.avi", video_target_size, audio_id, video_bitrate, video_codec, audio_codec, video_fourcc_override, video_gray_flag, video_crop_area, video_aspect_ratio, video_scale, video_encode_passes, video_deinterlace_flag, audio_volume_boost, audio_sample_rate, audio_bitrate, skip, sample_length) - cmd2 = build_compression_command (video_source_filename, "compression_test_2.avi", video_target_size, audio_id, video_bitrate, video_codec, audio_codec, video_fourcc_override, video_gray_flag, video_crop_area, video_aspect_ratio, video_scale, video_encode_passes, video_deinterlace_flag, audio_volume_boost, audio_sample_rate, audio_bitrate, skip*2, sample_length) - cmd3 = build_compression_command (video_source_filename, "compression_test_3.avi", video_target_size, audio_id, video_bitrate, video_codec, audio_codec, video_fourcc_override, video_gray_flag, video_crop_area, video_aspect_ratio, video_scale, video_encode_passes, video_deinterlace_flag, audio_volume_boost, audio_sample_rate, audio_bitrate, skip*4, sample_length) - cmd4 = build_compression_command (video_source_filename, "compression_test_4.avi", video_target_size, audio_id, video_bitrate, video_codec, audio_codec, video_fourcc_override, video_gray_flag, video_crop_area, video_aspect_ratio, video_scale, video_encode_passes, video_deinterlace_flag, audio_volume_boost, audio_sample_rate, audio_bitrate, skip*6, sample_length) - cmd5 = build_compression_command (video_source_filename, "compression_test_5.avi", video_target_size, audio_id, video_bitrate, video_codec, audio_codec, video_fourcc_override, video_gray_flag, video_crop_area, video_aspect_ratio, video_scale, video_encode_passes, video_deinterlace_flag, audio_volume_boost, audio_sample_rate, audio_bitrate, skip*8, sample_length) - run(cmd1) - run(cmd2) - run(cmd3) - run(cmd4) - run(cmd5) - size = get_filesize ("compression_test_1.avi")+get_filesize ("compression_test_2.avi")+get_filesize ("compression_test_3.avi")+get_filesize ("compression_test_4.avi")+get_filesize ("compression_test_5.avi") - return (size / 5.0) - -def compress_video (video_source_filename, video_final_filename, video_target_size, audio_id=128, video_bitrate=1000, video_codec='mpeg4', audio_codec='mp3', video_fourcc_override='FMP4', video_gray_flag=0, video_crop_area=None, video_aspect_ratio='16/9', video_scale=None, video_encode_passes=2, video_deinterlace_flag=0, audio_volume_boost=None, audio_sample_rate=None, audio_bitrate=None, seek_skip=None, seek_length=None, video_chapter=None, verbose_flag=0, dry_run_flag=0): - '''This compresses the video and audio of the given source video filename to the transcoded filename. - This does a two-pass compression (I'm assuming mpeg4, I should probably make this smarter for other formats). - ''' - # - # do the first pass video compression - # - #cmd = "mencoder -quiet '%(video_source_filename)s' -ss 65 -endpos 20 -aid %(audio_id)s -o '%(video_final_filename)s' -ffourcc %(video_fourcc_override)s -ovc lavc -oac lavc %(lavcopts)s %(video_filter)s %(audio_filter)s" % locals() - - cmd = build_compression_command (video_source_filename, video_final_filename, video_target_size, audio_id, video_bitrate, video_codec, audio_codec, video_fourcc_override, video_gray_flag, video_crop_area, video_aspect_ratio, video_scale, video_encode_passes, video_deinterlace_flag, audio_volume_boost, audio_sample_rate, audio_bitrate, seek_skip, seek_length, video_chapter) - if verbose_flag: print cmd - if not dry_run_flag: - run(cmd) - print - - # If not doing two passes then return early. - if video_encode_passes!='2': - return - - if verbose_flag: - video_actual_size = get_filesize (video_final_filename) - if video_actual_size > video_target_size: - print "=======================================================" - print "WARNING!" - print "First pass compression resulted in" - print "actual file size greater than target size." - print "Second pass will be too big." - print "=======================================================" - - # - # do the second pass video compression - # - cmd = cmd.replace ('vpass=1', 'vpass=2') - if verbose_flag: print cmd - if not dry_run_flag: - run(cmd) - print - return - -def compress_audio (audio_raw_filename, audio_compressed_filename, audio_lowpass_filter=None, audio_sample_rate=None, audio_bitrate=None, verbose_flag=0, dry_run_flag=0): - '''This is depricated. - This compresses the raw audio file to the compressed audio filename. - ''' - cmd = 'lame -h --athaa-sensitivity 1' # --cwlimit 11" - if audio_lowpass_filter: - cmd = cmd + ' --lowpass ' + audio_lowpass_filter - if audio_bitrate: - #cmd = cmd + ' --abr ' + audio_bitrate - cmd = cmd + ' --cbr -b ' + audio_bitrate - if audio_sample_rate: - cmd = cmd + ' --resample ' + audio_sample_rate - cmd = cmd + ' ' + audio_raw_filename + ' ' + audio_compressed_filename - if verbose_flag: print cmd - if not dry_run_flag: - (command_output, exitstatus) = run(cmd) - print - if exitstatus != 0: - raise Exception('ERROR: lame failed to compress raw audio file.') - -def mux (video_final_filename, video_transcoded_filename, audio_compressed_filename, video_container_format, verbose_flag=0, dry_run_flag=0): - '''This is depricated. I used to use a three-pass encoding where I would mix the audio track separately, but - this never worked very well (loss of audio sync).''' - if video_container_format.lower() == 'mkv': # Matroska - mux_mkv (video_final_filename, video_transcoded_filename, audio_compressed_filename, verbose_flag, dry_run_flag) - if video_container_format.lower() == 'avi': - mux_avi (video_final_filename, video_transcoded_filename, audio_compressed_filename, verbose_flag, dry_run_flag) - -def mux_mkv (video_final_filename, video_transcoded_filename, audio_compressed_filename, verbose_flag=0, dry_run_flag=0): - '''This is depricated.''' - cmd = 'mkvmerge -o %s --noaudio %s %s' % (video_final_filename, video_transcoded_filename, audio_compressed_filename) - if verbose_flag: print cmd - if not dry_run_flag: - run(cmd) - print - -def mux_avi (video_final_filename, video_transcoded_filename, audio_compressed_filename, verbose_flag=0, dry_run_flag=0): - '''This is depricated.''' - pass -# cmd = "mencoder -quiet -oac copy -ovc copy -o '%s' -audiofile %s '%s'" % (video_final_filename, audio_compressed_filename, video_transcoded_filename) -# if verbose_flag: print cmd -# if not dry_run_flag: -# run(cmd) -# print - -def delete_tmp_files (audio_raw_filename, verbose_flag=0, dry_run_flag=0): - global GLOBAL_LOGFILE_NAME - file_list = ' '.join([GLOBAL_LOGFILE_NAME, 'divx2pass.log', audio_raw_filename ]) - cmd = 'rm -f ' + file_list - if verbose_flag: print cmd - if not dry_run_flag: - run(cmd) - print - -############################################################################## -# This is the interactive Q&A that is used if a conf file was not given. -############################################################################## -def interactive_convert (): - - global prompts, prompts_key_order - - print globals()['__doc__'] - print - print "==============================================" - print " Enter '?' at any question to get extra help." - print "==============================================" - print - - # Ask for the level of options the user wants. - # A lot of code just to print a string! - level_sort = {0:'', 1:'', 2:''} - for k in prompts: - level = prompts[k][3] - if level < 0 or level > 2: - continue - level_sort[level] += " " + prompts[k][1] + "\n" - level_sort_string = "This sets the level for advanced options prompts. Set 0 for simple, 1 for advanced, or 2 for expert.\n" - level_sort_string += "[0] Basic options:\n" + str(level_sort[0]) + "\n" - level_sort_string += "[1] Advanced options:\n" + str(level_sort[1]) + "\n" - level_sort_string += "[2] Expert options:\n" + str(level_sort[2]) - c = input_option("Prompt level (0, 1, or 2)?", "1", level_sort_string) - max_prompt_level = int(c) - - options = {} - for k in prompts_key_order: - if k == 'video_aspect_ratio': - guess_aspect = get_aspect_ratio(options['video_source_filename']) - options[k] = input_option (prompts[k][1], guess_aspect, prompts[k][2], prompts[k][3], max_prompt_level) - elif k == 'audio_id': - aid_list = get_aid_list (options['video_source_filename']) - default_id = '128' - if max_prompt_level>=prompts[k][3]: - if len(aid_list) > 1: - print "This video has more than one audio stream. The following stream audio IDs were found:" - for aid in aid_list: - print " " + aid - default_id = aid_list[0] - else: - print "WARNING!" - print "Rippy was unable to get the list of audio streams from this video." - print "If reading directly from a DVD then the DVD device might be busy." - print "Using a default setting of stream id 128 (main audio on most DVDs)." - default_id = '128' - options[k] = input_option (prompts[k][1], default_id, prompts[k][2], prompts[k][3], max_prompt_level) - elif k == 'subtitle_id': - sid_list = get_sid_list (options['video_source_filename']) - default_id = 'None' - if max_prompt_level>=prompts[k][3]: - if len(sid_list) > 0: - print "This video has one or more subtitle streams. The following stream subtitle IDs were found:" - for sid in sid_list: - print " " + sid - #default_id = sid_list[0] - default_id = prompts[k][0] - else: - print "WARNING!" - print "Unable to get the list of subtitle streams from this video. It may have none." - print "Setting default to None." - default_id = 'None' - options[k] = input_option (prompts[k][1], default_id, prompts[k][2], prompts[k][3], max_prompt_level) - elif k == 'audio_lowpass_filter': - lowpass_default = "%.1f" % (math.floor(float(options['audio_sample_rate']) / 2.0)) - options[k] = input_option (prompts[k][1], lowpass_default, prompts[k][2], prompts[k][3], max_prompt_level) - elif k == 'video_bitrate': - if options['video_length'].lower() == 'none': - options[k] = input_option (prompts[k][1], '1000', prompts[k][2], prompts[k][3], max_prompt_level) - else: - options[k] = input_option (prompts[k][1], prompts[k][0], prompts[k][2], prompts[k][3], max_prompt_level) - else: - # don't bother asking for video_target_size or video_bitrate_overhead if video_bitrate was set - if (k=='video_target_size' or k=='video_bitrate_overhead') and options['video_bitrate']!='calc': - continue - # don't bother with crop area if video length is none - if k == 'video_crop_area' and options['video_length'].lower() == 'none': - options['video_crop_area'] = 'none' - continue - options[k] = input_option (prompts[k][1], prompts[k][0], prompts[k][2], prompts[k][3], max_prompt_level) - - #options['video_final_filename'] = options['video_final_filename'] + "." + options['video_container_format'] - - print "==========================================================================" - print "Ready to Rippy!" - print - print "The following options will be used:" - for k,v in options.iteritems(): - print "%27s : %s" % (k, v) - - print - c = input_option("Continue?", "Y") - c = c.strip().lower() - if c[0] != 'y': - print "Exiting..." - os._exit(1) - return options - -def clean_options (d): - '''This validates and cleans up the options dictionary. - After reading options interactively or from a conf file - we need to make sure that the values make sense and are - converted to the correct type. - 1. Any key with "_flag" in it becomes a boolean True or False. - 2. Values are normalized ("No", "None", "none" all become "none"; - "Calcluate", "c", "CALC" all become "calc"). - 3. Certain values are converted from string to int. - 4. Certain combinations of options are invalid or override each other. - This is a rather annoying function, but then so it most cleanup work. - ''' - for k in d: - d[k] = d[k].strip() - # convert all flag options to 0 or 1 - if '_flag' in k: - if type(d[k]) is types.StringType: - if d[k].strip().lower()[0] in 'yt1': #Yes, True, 1 - d[k] = 1 - else: - d[k] = 0 - d['video_bitrate'] = d['video_bitrate'].lower() - if d['video_bitrate'][0]=='c': - d['video_bitrate']='calc' - else: - d['video_bitrate'] = int(float(d['video_bitrate'])) - try: - d['video_target_size'] = int(d['video_target_size']) - # shorthand magic numbers get automatically expanded - if d['video_target_size'] == 180: - d['video_target_size'] = 193536000 - elif d['video_target_size'] == 550: - d['video_target_size'] = 580608000 - elif d['video_target_size'] == 650: - d['video_target_size'] = 681984000 - elif d['video_target_size'] == 700: - d['video_target_size'] = 737280000 - except: - d['video_target_size'] = 'none' - - try: - d['video_chapter'] = int(d['video_chapter']) - except: - d['video_chapter'] = None - - try: - d['subtitle_id'] = int(d['subtitle_id']) - except: - d['subtitle_id'] = None - - try: - d['video_bitrate_overhead'] = float(d['video_bitrate_overhead']) - except: - d['video_bitrate_overhead'] = -1.0 - - d['audio_bitrate'] = int(d['audio_bitrate']) - d['audio_sample_rate'] = int(d['audio_sample_rate']) - d['audio_volume_boost'] = d['audio_volume_boost'].lower() - if d['audio_volume_boost'][0]=='n': - d['audio_volume_boost'] = None - else: - d['audio_volume_boost'] = d['audio_volume_boost'].replace('db','') - d['audio_volume_boost'] = float(d['audio_volume_boost']) - -# assert (d['video_bitrate']=='calc' and d['video_target_size']!='none') -# or (d['video_bitrate']!='calc' and d['video_target_size']=='none') - - d['video_scale'] = d['video_scale'].lower() - if d['video_scale'][0]=='n': - d['video_scale']='none' - else: - al = re.findall("([0-9]+).*?([0-9]+)", d['video_scale']) - d['video_scale']=al[0][0]+':'+al[0][1] - d['video_crop_area'] = d['video_crop_area'].lower() - if d['video_crop_area'][0]=='n': - d['video_crop_area']='none' - d['video_length'] = d['video_length'].lower() - if d['video_length'][0]=='c': - d['video_length']='calc' - elif d['video_length'][0]=='n': - d['video_length']='none' - else: - d['video_length'] = int(float(d['video_length'])) - if d['video_length']==0: - d['video_length'] = 'none' - assert (not (d['video_length']=='none' and d['video_bitrate']=='calc')) - return d - -def main (): - try: - optlist, args = getopt.getopt(sys.argv[1:], 'h?', ['help','h','?']) - except Exception, e: - print str(e) - exit_with_usage() - command_line_options = dict(optlist) - # There are a million ways to cry for help. These are but a few of them. - if [elem for elem in command_line_options if elem in ['-h','--h','-?','--?','--help']]: - exit_with_usage(0) - - missing = check_missing_requirements() - if missing is not None: - print - print "==========================================================================" - print "ERROR!" - print "Some required external commands are missing." - print "please install the following packages:" - print str(missing) - print "==========================================================================" - print - c = input_option("Continue?", "Y") - c = c.strip().lower() - if c[0] != 'y': - print "Exiting..." - os._exit(1) - - if len(args) > 0: - # cute one-line string-to-dictionary parser (two-lines if you count this comment): - options = dict(re.findall('([^: \t\n]*)\s*:\s*(".*"|[^ \t\n]*)', file(args[0]).read())) - options = clean_options(options) - convert (options) - else: - options = interactive_convert () - options = clean_options(options) - convert (options) - print "# Done!" - -if __name__ == "__main__": - try: - start_time = time.time() - print time.asctime() - main() - print time.asctime() - print "TOTAL TIME IN MINUTES:", - print (time.time() - start_time) / 60.0 - except Exception, e: - tb_dump = traceback.format_exc() - print "==========================================================================" - print "ERROR -- Unexpected exception in script." - print str(e) - print str(tb_dump) - print "==========================================================================" - print >>GLOBAL_LOGFILE, "==========================================================================" - print >>GLOBAL_LOGFILE, "ERROR -- Unexpected exception in script." - print >>GLOBAL_LOGFILE, str(e) - print >>GLOBAL_LOGFILE, str(tb_dump) - print >>GLOBAL_LOGFILE, "==========================================================================" - exit_with_usage(3) - diff --git a/pexpect/examples/script.py b/pexpect/examples/script.py deleted file mode 100755 index 557fbf1..0000000 --- a/pexpect/examples/script.py +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env python - -'''This spawns a sub-shell (bash) and gives the user interactive control. The -entire shell session is logged to a file called script.log. This behaves much -like the classic BSD command 'script'. - -./script.py [-a] [-c command] {logfilename} - - logfilename : This is the name of the log file. Default is script.log. - -a : Append to log file. Default is to overwrite log file. - -c : spawn command. Default is to spawn the sh shell. - -Example: - - This will start a bash shell and append to the log named my_session.log: - - ./script.py -a -c bash my_session.log - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import os, sys, time, getopt -import signal, fcntl, termios, struct -import traceback -import pexpect - -global_pexpect_instance = None # Used by signal handler - -def exit_with_usage(): - - print globals()['__doc__'] - os._exit(1) - -def main(): - - ###################################################################### - # Parse the options, arguments, get ready, etc. - ###################################################################### - try: - optlist, args = getopt.getopt(sys.argv[1:], 'h?ac:', ['help','h','?']) - except Exception, e: - print str(e) - exit_with_usage() - options = dict(optlist) - if len(args) > 1: - exit_with_usage() - - if [elem for elem in options if elem in ['-h','--h','-?','--?','--help']]: - print "Help:" - exit_with_usage() - - if len(args) == 1: - script_filename = args[0] - else: - script_filename = "script.log" - if '-a' in options: - fout = file (script_filename, "ab") - else: - fout = file (script_filename, "wb") - if '-c' in options: - command = options['-c'] - else: - command = "sh" - - # Begin log with date/time in the form CCCCyymm.hhmmss - fout.write ('# %4d%02d%02d.%02d%02d%02d \n' % time.localtime()[:-3]) - - ###################################################################### - # Start the interactive session - ###################################################################### - p = pexpect.spawn(command) - p.logfile = fout - global global_pexpect_instance - global_pexpect_instance = p - signal.signal(signal.SIGWINCH, sigwinch_passthrough) - - print "Script recording started. Type ^] (ASCII 29) to escape from the script shell." - p.interact(chr(29)) - fout.close() - return 0 - -def sigwinch_passthrough (sig, data): - - # Check for buggy platforms (see pexpect.setwinsize()). - if 'TIOCGWINSZ' in dir(termios): - TIOCGWINSZ = termios.TIOCGWINSZ - else: - TIOCGWINSZ = 1074295912 # assume - s = struct.pack ("HHHH", 0, 0, 0, 0) - a = struct.unpack ('HHHH', fcntl.ioctl(sys.stdout.fileno(), TIOCGWINSZ , s)) - global global_pexpect_instance - global_pexpect_instance.setwinsize(a[0],a[1]) - -if __name__ == "__main__": - try: - main() - except SystemExit, e: - raise e - except Exception, e: - print "ERROR" - print str(e) - traceback.print_exc() - os._exit(1) - diff --git a/pexpect/examples/ssh_session.py b/pexpect/examples/ssh_session.py deleted file mode 100755 index 91499ce..0000000 --- a/pexpect/examples/ssh_session.py +++ /dev/null @@ -1,118 +0,0 @@ -#!/usr/bin/env python - -''' - Eric S. Raymond - - Greatly modified by Nigel W. Moriarty - April 2003 - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -from pexpect import * -import os, sys -import getpass -import time - - -class ssh_session: - - '''Session with extra state including the password to be used.''' - - def __init__(self, user, host, password=None, verbose=0): - - self.user = user - self.host = host - self.verbose = verbose - self.password = password - self.keys = [ - 'authenticity', - 'assword:', - '@@@@@@@@@@@@', - 'Command not found.', - EOF, - ] - - self.f = open('ssh.out','w') - - def __repr__(self): - - outl = 'class :'+self.__class__.__name__ - for attr in self.__dict__: - if attr == 'password': - outl += '\n\t'+attr+' : '+'*'*len(self.password) - else: - outl += '\n\t'+attr+' : '+str(getattr(self, attr)) - return outl - - def __exec(self, command): - - '''Execute a command on the remote host. Return the output.''' - - child = spawn(command, - #timeout=10, - ) - if self.verbose: - sys.stderr.write("-> " + command + "\n") - seen = child.expect(self.keys) - self.f.write(str(child.before) + str(child.after)+'\n') - if seen == 0: - child.sendline('yes') - seen = child.expect(self.keys) - if seen == 1: - if not self.password: - self.password = getpass.getpass('Remote password: ') - child.sendline(self.password) - child.readline() - time.sleep(5) - # Added to allow the background running of remote process - if not child.isalive(): - seen = child.expect(self.keys) - if seen == 2: - lines = child.readlines() - self.f.write(lines) - if self.verbose: - sys.stderr.write("<- " + child.before + "|\n") - try: - self.f.write(str(child.before) + str(child.after)+'\n') - except: - pass - self.f.close() - return child.before - - def ssh(self, command): - - return self.__exec("ssh -l %s %s \"%s\"" \ - % (self.user,self.host,command)) - - def scp(self, src, dst): - - return self.__exec("scp %s %s@%s:%s" \ - % (src, session.user, session.host, dst)) - - def exists(self, file): - - '''Retrieve file permissions of specified remote file.''' - - seen = self.ssh("/bin/ls -ld %s" % file) - if string.find(seen, "No such file") > -1: - return None # File doesn't exist - else: - return seen.split()[0] # Return permission field of listing. - diff --git a/pexpect/examples/ssh_tunnel.py b/pexpect/examples/ssh_tunnel.py deleted file mode 100755 index 5587f40..0000000 --- a/pexpect/examples/ssh_tunnel.py +++ /dev/null @@ -1,94 +0,0 @@ -#!/usr/bin/env python - -'''This starts an SSH tunnel to a given host. If the SSH process ever dies then -this script will detect that and restart it. I use this under Cygwin to keep -open encrypted tunnels to port 25 (SMTP), port 143 (IMAP4), and port 110 -(POP3). I set my mail client to talk to localhost and I keep this script -running in the background. - -Note that this is a rather stupid script at the moment because it just looks to -see if any ssh process is running. It should really make sure that our specific -ssh process is running. The problem is that ssh is missing a very useful -feature. It has no way to report the process id of the background daemon that -it creates with the -f command. This would be a really useful script if I could -figure a way around this problem. - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import pexpect -import getpass -import time - -# SMTP:25 IMAP4:143 POP3:110 -tunnel_command = 'ssh -C -N -f -L 25:127.0.0.1:25 -L 143:127.0.0.1:143 -L 110:127.0.0.1:110 %(user)@%(host)' -host = raw_input('Hostname: ') -user = raw_input('Username: ') -X = getpass.getpass('Password: ') - -def get_process_info (): - - # This seems to work on both Linux and BSD, but should otherwise be considered highly UNportable. - - ps = pexpect.run ('ps ax -O ppid') - pass - -def start_tunnel (): - - try: - ssh_tunnel = pexpect.spawn (tunnel_command % globals()) - ssh_tunnel.expect ('password:') - time.sleep (0.1) - ssh_tunnel.sendline (X) - time.sleep (60) # Cygwin is slow to update process status. - ssh_tunnel.expect (pexpect.EOF) - - except Exception, e: - print str(e) - -def main (): - - while True: - ps = pexpect.spawn ('ps') - time.sleep (1) - index = ps.expect (['/usr/bin/ssh', pexpect.EOF, pexpect.TIMEOUT]) - if index == 2: - print 'TIMEOUT in ps command...' - print str(ps) - time.sleep (13) - if index == 1: - print time.asctime(), - print 'restarting tunnel' - start_tunnel () - time.sleep (11) - print 'tunnel OK' - else: - # print 'tunnel OK' - time.sleep (7) - -if __name__ == '__main__': - - main () - -# This was for older SSH versions that didn't have -f option -#tunnel_command = 'ssh -C -n -L 25:%(host)s:25 -L 110:%(host)s:110 %(user)s@%(host)s -f nothing.sh' -#nothing_script = '''#!/bin/sh -#while true; do sleep 53; done -#''' - diff --git a/pexpect/examples/sshls.py b/pexpect/examples/sshls.py deleted file mode 100755 index 731dc6c..0000000 --- a/pexpect/examples/sshls.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python - -'''This runs 'ls -l' on a remote host using SSH. -At the prompts enter hostname, username, and password. - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import pexpect -import getpass, os - -def ssh_command (user, host, password, command): - - '''This runs a command on the remote host. This could also be done with the - pxssh class, but this demonstrates what that class does at a simpler level. - This returns a pexpect.spawn object. This handles the case when you try to - connect to a new host and ssh asks you if you want to accept the public key - fingerprint and continue connecting. ''' - - ssh_newkey = 'Are you sure you want to continue connecting' - child = pexpect.spawn('ssh -l %s %s %s'%(user, host, command)) - i = child.expect([pexpect.TIMEOUT, ssh_newkey, 'password: ']) - if i == 0: # Timeout - print 'ERROR!' - print 'SSH could not login. Here is what SSH said:' - print child.before, child.after - return None - if i == 1: # SSH does not have the public key. Just accept it. - child.sendline ('yes') - child.expect ('password: ') - i = child.expect([pexpect.TIMEOUT, 'password: ']) - if i == 0: # Timeout - print 'ERROR!' - print 'SSH could not login. Here is what SSH said:' - print child.before, child.after - return None - child.sendline(password) - return child - -def main (): - - host = raw_input('Hostname: ') - user = raw_input('User: ') - password = getpass.getpass('Password: ') - child = ssh_command (user, host, password, '/bin/ls -l') - child.expect(pexpect.EOF) - print child.before - -if __name__ == '__main__': - - try: - main() - except Exception, e: - print str(e) - traceback.print_exc() - os._exit(1) - diff --git a/pexpect/examples/table_test.html b/pexpect/examples/table_test.html deleted file mode 100644 index 5dba0ec..0000000 --- a/pexpect/examples/table_test.html +++ /dev/null @@ -1,106 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> -<html> -<head> -<title>TEST</title> -</head> -<style type="text/css"> -a {color: #9f9; text-decoration: none} -a:hover {color: #0f0} -hr {color: #0f0} -html,table,body,textarea,input,form -{ -font-family: "Courier New", Courier, mono; -font-size: 8pt; -color: #0c0; -background-color: #020; -margin:0; -padding:0; -border:0; -} -input { background-color: #010; } -textarea { -border-width:1; -border-style:solid; -border-color:#0c0; -padding:3; -margin:3; -} -</style> -<script> -var foo="" + -" 123456789012345678901234567890123456789012345 789012345678901234567890123456789"+ -"0 2345678901234567890123456789012345678901234 6 89012345678901234567890123456789"+ -"01 34567890123456789012345678901234567890123 567 9012345678901234567890123456789"+ -"012 456789012345678901234567890123456789012 45678 012345678901234567890123456789"+ -"0123 5678901234567890123456789012345678901 3456789 12345678901234567890123456789"+ -"01234 67890123456789012345678901234567890 234567890 2345678901234567890123456789"+ -"012345 789012345678901234567890123456789 12345678901 345678901234567890123456789"+ -"0123456 8901234567890123456789012345678 0123456789012 45678901234567890123456789"+ -"01234567 90123456789012345678901234567 901234567890123 5678901234567890123456789"+ -"012345678 012345678901234567890123456 89012345678901234 678901234567890123456789"+ -"0123456789 1234567890123456789012345 7890123456789012345 78901234567890123456789"+ -"01234567890 23456789012345678901234 678901234567890123456 8901234567890123456789"+ -"012345678901 345678901234567890123 56789012345678901234567 901234567890123456789"+ -"0123456789012 4567890123456789012 4567890123456789012345678 0123456789012345678 "+ -"01234567890123 56789012345678901 345678901234567890123456789 12345678901234567 9"+ -"012345678901234 678901234567890 23456789012 567 01234567890 234567890123456 89"+ -"0123456789012345 7890123456789 123457789012 567 012345678901 3456789012345 789"+ -"01234567890123456 89012345678 012345678901234567890123456789012 45678901234 6789"+ -"012345678901234567 901234567 90123456789 12345678901 34567890123 567890123 56789"+ -"0123456789012345678 0123456 8901234567890 3456789 2345678901234 6789012 456789"+ -"01234567890123456789 12345 7890123456789012 0123456789012345 78901 3456789"+ -"012345678901234567890 234 67890123456789012345678901234567890123456 890 23456789"+ -"0123456789012345678901 3 5678901234567890123456789012345678901234567 9 123456789"+ -"01234567890123456789012 456789012345678901234567890123456789012345678 0123456789"; -function start2() -{ - // get the reference for the body - //var mybody = document.getElementsByTagName("body")[0]; - var mybody = document.getElementById("replace_me"); - var myroot = document.getElementById("a_parent"); - mytable = document.createElement("table"); - mytablebody = document.createElement("tbody"); - mytable.setAttribute("border","0"); - mytable.setAttribute("cellspacing","0"); - mytable.setAttribute("cellpadding","0"); - for(var j = 0; j < 24; j++) - { - mycurrent_row = document.createElement("tr"); - for(var i = 0; i < 80; i++) - { - mycurrent_cell = document.createElement("td"); - offset = (j*80)+i; - currenttext = document.createTextNode(foo.substring(offset,offset+1)); - mycurrent_cell.appendChild(currenttext); - mycurrent_row.appendChild(mycurrent_cell); - } - mytablebody.appendChild(mycurrent_row); - } - mytable.appendChild(mytablebody); - myroot.replaceChild(mytable,mybody); - //mybody.appendChild(mytable); -} -</script> -<body onload="start2();"> -<table align="LEFT" border="0" cellspacing="0" cellpadding="0"> -<div id="a_parent"> -<span id="replace_me"> -<tr align="left" valign="left"> - <td>/</td> - <td>h</td> - <td>o</td> - <td>m</td> - <td>e</td> - <td>/</td> - <td>n</td> - <td>o</td> - <td>a</td> - <td>h</td> - <td>/</td> - <td> </td> -</tr> -</table> -</span> -</div> -</body> -</html>
\ No newline at end of file diff --git a/pexpect/examples/topip.py b/pexpect/examples/topip.py deleted file mode 100755 index 4f57067..0000000 --- a/pexpect/examples/topip.py +++ /dev/null @@ -1,301 +0,0 @@ -#!/usr/bin/env python - -''' This runs netstat on a local or remote server. It calculates some simple -statistical information on the number of external inet connections. It groups -by IP address. This can be used to detect if one IP address is taking up an -excessive number of connections. It can also send an email alert if a given IP -address exceeds a threshold between runs of the script. This script can be used -as a drop-in Munin plugin or it can be used stand-alone from cron. I used this -on a busy web server that would sometimes get hit with denial of service -attacks. This made it easy to see if a script was opening many multiple -connections. A typical browser would open fewer than 10 connections at once. -A script might open over 100 simultaneous connections. - -./topip.py [-s server_hostname] [-u username] [-p password] - {-a from_addr,to_addr} {-n N} {-v} {--ipv6} - - -s : hostname of the remote server to login to. - -u : username to user for login. - -p : password to user for login. - -n : print stddev for the the number of the top 'N' ipaddresses. - -v : verbose - print stats and list of top ipaddresses. - -a : send alert if stddev goes over 20. - -l : to log message to /var/log/topip.log - --ipv6 : this parses netstat output that includes ipv6 format. - Note that this actually only works with ipv4 addresses, but for - versions of netstat that print in ipv6 format. - --stdev=N : Where N is an integer. This sets the trigger point - for alerts and logs. Default is to trigger if the - max value is over 5 standard deviations. - -Example: - - This will print stats for the top IP addresses connected to the given host: - - ./topip.py -s www.example.com -u mylogin -p mypassword -n 10 -v - - This will send an alert email if the maxip goes over the stddev trigger - value and the the current top ip is the same as the last top ip - (/tmp/topip.last): - - ./topip.py -s www.example.com -u mylogin -p mypassword \\ - -n 10 -v -a alert@example.com,user@example.com - - This will print the connection stats for the localhost in Munin format: - - ./topip.py - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -# See http://pexpect.sourceforge.net/ -import pexpect -import pxssh -import os -import sys -import time -import re -import getopt -import pickle -import getpass -import smtplib -import traceback -from pprint import pprint - -TOPIP_LOG_FILE = '/var/log/topip.log' -TOPIP_LAST_RUN_STATS = '/var/run/topip.last' - -def exit_with_usage(): - - print globals()['__doc__'] - os._exit(1) - -def stats(r): - - '''This returns a dict of the median, average, standard deviation, - min and max of the given sequence. - - >>> from topip import stats - >>> print stats([5,6,8,9]) - {'med': 8, 'max': 9, 'avg': 7.0, 'stddev': 1.5811388300841898, 'min': 5} - >>> print stats([1000,1006,1008,1014]) - {'med': 1008, 'max': 1014, 'avg': 1007.0, 'stddev': 5.0, 'min': 1000} - >>> print stats([1,3,4,5,18,16,4,3,3,5,13]) - {'med': 4, 'max': 18, 'avg': 6.8181818181818183, 'stddev': 5.6216817577237475, 'min': 1} - >>> print stats([1,3,4,5,18,16,4,3,3,5,13,14,5,6,7,8,7,6,6,7,5,6,4,14,7]) - {'med': 6, 'max': 18, 'avg': 7.0800000000000001, 'stddev': 4.3259218670706474, 'min': 1} - ''' - - total = sum(r) - avg = float(total)/float(len(r)) - sdsq = sum([(i-avg)**2 for i in r]) - s = list(r) - s.sort() - return dict(zip(['med', 'avg', 'stddev', 'min', 'max'], - (s[len(s)//2], avg, (sdsq/len(r))**.5, min(r), max(r)))) - -def send_alert (message, subject, addr_from, addr_to, smtp_server='localhost'): - - '''This sends an email alert. - ''' - - message = ( 'From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n' - % (addr_from, addr_to, subject) + message ) - server = smtplib.SMTP(smtp_server) - server.sendmail(addr_from, addr_to, message) - server.quit() - -def main(): - - # Parse the options, arguments, etc. - try: - optlist, args = getopt.getopt(sys.argv[1:], - 'h?valqs:u:p:n:', ['help','h','?','ipv6','stddev=']) - except Exception, e: - print str(e) - exit_with_usage() - options = dict(optlist) - - munin_flag = False - if len(args) > 0: - if args[0] == 'config': - print 'graph_title Netstat Connections per IP' - print 'graph_vlabel Socket connections per IP' - print 'connections_max.label max' - print 'connections_max.info Maximum number of connections per IP' - print 'connections_avg.label avg' - print 'connections_avg.info Average number of connections per IP' - print 'connections_stddev.label stddev' - print 'connections_stddev.info Standard deviation' - return 0 - elif args[0] != '': - print args, len(args) - return 0 - exit_with_usage() - if [elem for elem in options if elem in ['-h','--h','-?','--?','--help']]: - print 'Help:' - exit_with_usage() - if '-s' in options: - hostname = options['-s'] - else: - # if host was not specified then assume localhost munin plugin. - munin_flag = True - hostname = 'localhost' - # If localhost then don't ask for username/password. - if hostname != 'localhost' and hostname != '127.0.0.1': - if '-u' in options: - username = options['-u'] - else: - username = raw_input('username: ') - if '-p' in options: - password = options['-p'] - else: - password = getpass.getpass('password: ') - else: - use_localhost = True - - if '-l' in options: - log_flag = True - else: - log_flag = False - if '-n' in options: - average_n = int(options['-n']) - else: - average_n = None - if '-v' in options: - verbose = True - else: - verbose = False - if '-a' in options: - alert_flag = True - (alert_addr_from, alert_addr_to) = tuple(options['-a'].split(',')) - else: - alert_flag = False - if '--ipv6' in options: - ipv6_flag = True - else: - ipv6_flag = False - if '--stddev' in options: - stddev_trigger = float(options['--stddev']) - else: - stddev_trigger = 5 - - if ipv6_flag: - netstat_pattern = '(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+::ffff:(\S+):(\S+)\s+.*?\r' - else: - netstat_pattern = '(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(?:::ffff:)*(\S+):(\S+)\s+.*?\r' - #netstat_pattern = '(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+):(\S+)\s+.*?\r' - - # run netstat (either locally or via SSH). - if use_localhost: - p = pexpect.spawn('netstat -n -t') - PROMPT = pexpect.TIMEOUT - else: - p = pxssh.pxssh() - p.login(hostname, username, password) - p.sendline('netstat -n -t') - PROMPT = p.PROMPT - - # For each matching netstat_pattern put the ip address in the list. - ip_list = {} - try: - while 1: - i = p.expect([PROMPT, netstat_pattern]) - if i == 0: - break - k = p.match.groups()[4] - if k in ip_list: - ip_list[k] = ip_list[k] + 1 - else: - ip_list[k] = 1 - except: - pass - - # remove a few common, uninteresting addresses from the dictionary. - ip_list = dict([ (key,value) for key,value in ip_list.items() if '192.168.' not in key]) - ip_list = dict([ (key,value) for key,value in ip_list.items() if '127.0.0.1' not in key]) - - # sort dict by value (count) - #ip_list = sorted(ip_list.iteritems(), - # lambda x,y:cmp(x[1], y[1]),reverse=True) - ip_list = ip_list.items() - if len(ip_list) < 1: - if verbose: print 'Warning: no networks connections worth looking at.' - return 0 - ip_list.sort(lambda x,y:cmp(y[1],x[1])) - - # generate some stats for the ip addresses found. - if average_n <= 1: - average_n = None - # Reminder: the * unary operator treats the list elements as arguments. - s = stats(zip(*ip_list[0:average_n])[1]) - s['maxip'] = ip_list[0] - - # print munin-style or verbose results for the stats. - if munin_flag: - print 'connections_max.value', s['max'] - print 'connections_avg.value', s['avg'] - print 'connections_stddev.value', s['stddev'] - return 0 - if verbose: - pprint (s) - print - pprint (ip_list[0:average_n]) - - # load the stats from the last run. - try: - last_stats = pickle.load(file(TOPIP_LAST_RUN_STATS)) - except: - last_stats = {'maxip':None} - - if ( s['maxip'][1] > (s['stddev'] * stddev_trigger) - and s['maxip']==last_stats['maxip'] ): - if verbose: print 'The maxip has been above trigger for two consecutive samples.' - if alert_flag: - if verbose: print 'SENDING ALERT EMAIL' - send_alert(str(s), 'ALERT on %s' - % hostname, alert_addr_from, alert_addr_to) - if log_flag: - if verbose: print 'LOGGING THIS EVENT' - fout = file(TOPIP_LOG_FILE,'a') - #dts = time.strftime('%Y:%m:%d:%H:%M:%S', time.localtime()) - dts = time.asctime() - fout.write ('%s - %d connections from %s\n' - % (dts,s['maxip'][1],str(s['maxip'][0]))) - fout.close() - - # save state to TOPIP_LAST_RUN_STATS - try: - pickle.dump(s, file(TOPIP_LAST_RUN_STATS,'w')) - os.chmod (TOPIP_LAST_RUN_STATS, 0664) - except: - pass - # p.logout() - -if __name__ == '__main__': - try: - main() - sys.exit(0) - except SystemExit, e: - raise e - except Exception, e: - print str(e) - traceback.print_exc() - os._exit(1) - diff --git a/pexpect/examples/uptime.py b/pexpect/examples/uptime.py deleted file mode 100755 index 3316600..0000000 --- a/pexpect/examples/uptime.py +++ /dev/null @@ -1,73 +0,0 @@ -#!/usr/bin/env python - -'''This displays uptime information using uptime. This is redundant, -but it demonstrates expecting for a regular expression that uses subgroups. - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import pexpect -import re - -# There are many different styles of uptime results. I try to parse them all. Yeee! -# Examples from different machines: -# [x86] Linux 2.4 (Redhat 7.3) -# 2:06pm up 63 days, 18 min, 3 users, load average: 0.32, 0.08, 0.02 -# [x86] Linux 2.4.18-14 (Redhat 8.0) -# 3:07pm up 29 min, 1 user, load average: 2.44, 2.51, 1.57 -# [PPC - G4] MacOS X 10.1 SERVER Edition -# 2:11PM up 3 days, 13:50, 3 users, load averages: 0.01, 0.00, 0.00 -# [powerpc] Darwin v1-58.corefa.com 8.2.0 Darwin Kernel Version 8.2.0 -# 10:35 up 18:06, 4 users, load averages: 0.52 0.47 0.36 -# [Sparc - R220] Sun Solaris (8) -# 2:13pm up 22 min(s), 1 user, load average: 0.02, 0.01, 0.01 -# [x86] Linux 2.4.18-14 (Redhat 8) -# 11:36pm up 4 days, 17:58, 1 user, load average: 0.03, 0.01, 0.00 -# AIX jwdir 2 5 0001DBFA4C00 -# 09:43AM up 23:27, 1 user, load average: 0.49, 0.32, 0.23 -# OpenBSD box3 2.9 GENERIC#653 i386 -# 6:08PM up 4 days, 22:26, 1 user, load averages: 0.13, 0.09, 0.08 - -# This parses uptime output into the major groups using regex group matching. -p = pexpect.spawn ('uptime') -p.expect('up\s+(.*?),\s+([0-9]+) users?,\s+load averages?: ([0-9]+\.[0-9][0-9]),?\s+([0-9]+\.[0-9][0-9]),?\s+([0-9]+\.[0-9][0-9])') -duration, users, av1, av5, av15 = p.match.groups() - -# The duration is a little harder to parse because of all the different -# styles of uptime. I'm sure there is a way to do this all at once with -# one single regex, but I bet it would be hard to read and maintain. -# If anyone wants to send me a version using a single regex I'd be happy to see it. -days = '0' -hours = '0' -mins = '0' -if 'day' in duration: - p.match = re.search('([0-9]+)\s+day',duration) - days = str(int(p.match.group(1))) -if ':' in duration: - p.match = re.search('([0-9]+):([0-9]+)',duration) - hours = str(int(p.match.group(1))) - mins = str(int(p.match.group(2))) -if 'min' in duration: - p.match = re.search('([0-9]+)\s+min',duration) - mins = str(int(p.match.group(1))) - -# Print the parsed fields in CSV format. -print 'days, hours, minutes, users, cpu avg 1 min, cpu avg 5 min, cpu avg 15 min' -print '%s, %s, %s, %s, %s, %s, %s' % (days, hours, mins, users, av1, av5, av15) - diff --git a/pexpect/fdpexpect.py b/pexpect/fdpexpect.py deleted file mode 100644 index 38b09b6..0000000 --- a/pexpect/fdpexpect.py +++ /dev/null @@ -1,99 +0,0 @@ -'''This is like pexpect, but it will work with any file descriptor that you -pass it. You are reponsible for opening and close the file descriptor. -This allows you to use Pexpect with sockets and named pipes (FIFOs). - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -from pexpect import * -import os - -__all__ = ['fdspawn'] - -class fdspawn (spawn): - - '''This is like pexpect.spawn but allows you to supply your own open file - descriptor. For example, you could use it to read through a file looking - for patterns, or to control a modem or serial device. ''' - - def __init__ (self, fd, args=[], timeout=30, maxread=2000, searchwindowsize=None, logfile=None): - - '''This takes a file descriptor (an int) or an object that support the - fileno() method (returning an int). All Python file-like objects - support fileno(). ''' - - ### TODO: Add better handling of trying to use fdspawn in place of spawn - ### TODO: (overload to allow fdspawn to also handle commands as spawn does. - - if type(fd) != type(0) and hasattr(fd, 'fileno'): - fd = fd.fileno() - - if type(fd) != type(0): - raise ExceptionPexpect ('The fd argument is not an int. If this is a command string then maybe you want to use pexpect.spawn.') - - try: # make sure fd is a valid file descriptor - os.fstat(fd) - except OSError: - raise ExceptionPexpect, 'The fd argument is not a valid file descriptor.' - - self.args = None - self.command = None - spawn.__init__(self, None, args, timeout, maxread, searchwindowsize, logfile) - self.child_fd = fd - self.own_fd = False - self.closed = False - self.name = '<file descriptor %d>' % fd - - def __del__ (self): - - return - - def close (self): - - if self.child_fd == -1: - return - if self.own_fd: - self.close (self) - else: - self.flush() - os.close(self.child_fd) - self.child_fd = -1 - self.closed = True - - def isalive (self): - - '''This checks if the file descriptor is still valid. If os.fstat() - does not raise an exception then we assume it is alive. ''' - - if self.child_fd == -1: - return False - try: - os.fstat(self.child_fd) - return True - except: - return False - - def terminate (self, force=False): - - raise ExceptionPexpect ('This method is not valid for file descriptors.') - - def kill (self, sig): - - return - diff --git a/pexpect/notes/my_forkpty.py b/pexpect/notes/my_forkpty.py deleted file mode 100644 index f2bef23..0000000 --- a/pexpect/notes/my_forkpty.py +++ /dev/null @@ -1,89 +0,0 @@ -import os, fcntl, termios -import time - -def my_forkpty(): - - (master_fd, slave_fd) = os.openpty() - - if (master_fd < 0 or slave_fd < 0): - raise ExceptionPexpect("Forkpty failed") - - # slave_name = ptsname(master_fd); - - pid = os.fork(); - if pid == -1: - raise ExceptionPexpect("Forkpty failed") - elif pid == 0: # Child - if hasattr(termios, 'TIOCNOTTY'): - # Some platforms require an explicit detach of the - # current controlling tty before closing stdin, stdout, stderr. - # OpenBSD says that this is obsolete, but doesn't hurt. - try: - fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY) - except: - pass - else: #if fd >= 0: - fcntl.ioctl(fd, termios.TIOCNOTTY, 0) - os.close(fd) - - # The setsid() system call will place the process into its own session - # which has the effect of disassociating it from the controlling terminal. - # This is known to be true for OpenBSD. - os.setsid() - # except: return posix_error(); - - # Verify that we are disconnected from the controlling tty. - try: - fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY) - os.close(fd) - raise ExceptionPexpect("Forkpty failed") - except: - pass - if 'TIOCSCTTY' in dir(termios): - # Make the pseudo terminal the controlling terminal for this process - # (the process must not currently have a controlling terminal). - if fcntl.ioctl(slave_fd, termios.TIOCSCTTY, '') < 0: - raise ExceptionPexpect("Forkpty failed") - -# # Verify that we can open to the slave pty file. */ -# fd = os.open(slave_name, os.O_RDWR); -# if fd < 0: -# raise ExceptionPexpect("Forkpty failed") -# else: -# os.close(fd); - - # Verify that we now have a controlling tty. - fd = os.open("/dev/tty", os.O_WRONLY) - if fd < 0: - raise ExceptionPexpect("This process could not get a controlling tty.") - else: - os.close(fd) - - os.close(master_fd) - os.dup2(slave_fd, 0) - os.dup2(slave_fd, 1) - os.dup2(slave_fd, 2) - if slave_fd > 2: - os.close(slave_fd) - pid = 0 - - else: - # PARENT - os.close(slave_fd); - - if pid == -1: - raise ExceptionPexpect("This process could not get a controlling tty.") -# if (pid == 0) -# PyOS_AfterFork(); - - return (pid, master_fd) - -pid, fd = my_forkpty () -if pid == 0: # child - print 'I am not a robot!' -else: - print '(pid, fd) = (%d, %d)' % (pid, fd) - time.sleep(1) # Give the child a chance to print. - print 'Robots always say:', os.read(fd,100) - os.close(fd) - diff --git a/pexpect/notes/notes.txt b/pexpect/notes/notes.txt deleted file mode 100644 index a793587..0000000 --- a/pexpect/notes/notes.txt +++ /dev/null @@ -1,50 +0,0 @@ - -#################### -# -# NOTES -# -#################### - -## def send_human(self, text, delay_min = 0, delay_max = 1): -## pass -## def spawn2(self, command, args): -## """return pid, fd_stdio, fd_stderr -## """ -## pass - - -# Reason for double fork: -# http://www.erlenstar.demon.co.uk/unix/faq_2.html#SEC15 -# Reason for ptys: -# http://www.erlenstar.demon.co.uk/unix/faq_4.html#SEC52 - -# Nonblocking on Win32? -# Reasearch this as a way to maybe make pipe work for Win32. -# http://groups.google.com/groups?q=setraw+tty&hl=en&selm=uvgpvisvk.fsf%40roundpoint.com&rnum=7 -# -# if istty: -# if os.name=='posix': -# import tty -# tty.setraw(sys.stdin.fileno()) -# elif os.name=='nt': -# import win32file, win32con -# hstdin = win32file._get_osfhandle(sys.stdin.fileno()) -# modes = (win32file.GetConsoleMode(hstdin) -# & ~(win32con.ENABLE_LINE_INPUT -# |win32con.ENABLE_ECHO_INPUT)) -# win32file.SetConsoleMode(hstdin, modes) - -# Basic documentation: -# Explain use of lists of patterns and return index. -# Explain exceptions for non-handled special cases like EOF - -# Test bad fork -# Test ENOENT. In other words, no more TTY devices. - -#GLOBAL_SIGCHLD_RECEIVED = 0 -#def childdied (signum, frame): -# print 'Signal handler called with signal', signum -# frame.f_globals['pexpect'].GLOBAL_SIGCHLD_RECEIVED = 1 -# print str(frame.f_globals['pexpect'].GLOBAL_SIGCHLD_RECEIVED) -# GLOBAL_SIGCHLD_RECEIVED = 1 - diff --git a/pexpect/notes/posixmodule.c.diff b/pexpect/notes/posixmodule.c.diff deleted file mode 100644 index 3bea1f9..0000000 --- a/pexpect/notes/posixmodule.c.diff +++ /dev/null @@ -1,233 +0,0 @@ -*** Python-2.2.1.orig/Modules/posixmodule.c Tue Mar 12 16:38:31 2002 ---- Python-2.2.1/Modules/posixmodule.c Tue May 21 01:16:29 2002 -*************** -*** 1904,1910 **** - } - #endif - -! #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) - #ifdef HAVE_PTY_H - #include <pty.h> - #else ---- 1904,1913 ---- - } - #endif - -! #if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(sun) -! #ifdef sun -! #include <sys/stropts.h> -! #endif - #ifdef HAVE_PTY_H - #include <pty.h> - #else -*************** -*** 1914,1920 **** - #endif /* HAVE_PTY_H */ - #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */ - -! #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) - static char posix_openpty__doc__[] = - "openpty() -> (master_fd, slave_fd)\n\ - Open a pseudo-terminal, returning open fd's for both master and slave end.\n"; ---- 1917,1923 ---- - #endif /* HAVE_PTY_H */ - #endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) */ - -! #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(sun) - static char posix_openpty__doc__[] = - "openpty() -> (master_fd, slave_fd)\n\ - Open a pseudo-terminal, returning open fd's for both master and slave end.\n"; -*************** -*** 1925,1932 **** - int master_fd, slave_fd; - #ifndef HAVE_OPENPTY - char * slave_name; - #endif -! - if (!PyArg_ParseTuple(args, ":openpty")) - return NULL; - ---- 1928,1941 ---- - int master_fd, slave_fd; - #ifndef HAVE_OPENPTY - char * slave_name; -+ #ifdef sun -+ void *sig_saved; - #endif -! #endif -! #if !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY) && defined(sun) -! extern char *ptsname(); -! #endif -! - if (!PyArg_ParseTuple(args, ":openpty")) - return NULL; - -*************** -*** 1933,1939 **** - #ifdef HAVE_OPENPTY - if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0) - return posix_error(); -! #else - slave_name = _getpty(&master_fd, O_RDWR, 0666, 0); - if (slave_name == NULL) - return posix_error(); ---- 1942,1948 ---- - #ifdef HAVE_OPENPTY - if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0) - return posix_error(); -! #elif HAVE__GETPTY - slave_name = _getpty(&master_fd, O_RDWR, 0666, 0); - if (slave_name == NULL) - return posix_error(); -*************** -*** 1941,1946 **** ---- 1950,1966 ---- - slave_fd = open(slave_name, O_RDWR); - if (slave_fd < 0) - return posix_error(); -+ #else -+ master_fd = open("/dev/ptmx", O_RDWR|O_NOCTTY); /* open master */ -+ sig_saved = signal(SIGCHLD, SIG_DFL); -+ grantpt(master_fd); /* change permission of slave */ -+ unlockpt(master_fd); /* unlock slave */ -+ signal(SIGCHLD,sig_saved); -+ slave_name = ptsname(master_fd); /* get name of slave */ -+ slave_fd = open(slave_name, O_RDWR); /* open slave */ -+ ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */ -+ ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm*/ -+ ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat*/ - #endif /* HAVE_OPENPTY */ - - return Py_BuildValue("(ii)", master_fd, slave_fd); -*************** -*** 1948,1954 **** - } - #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */ - -! #ifdef HAVE_FORKPTY - static char posix_forkpty__doc__[] = - "forkpty() -> (pid, master_fd)\n\ - Fork a new process with a new pseudo-terminal as controlling tty.\n\n\ ---- 1968,1974 ---- - } - #endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) */ - -! #if defined(HAVE_FORKPTY) || defined(sun) - static char posix_forkpty__doc__[] = - "forkpty() -> (pid, master_fd)\n\ - Fork a new process with a new pseudo-terminal as controlling tty.\n\n\ -*************** -*** 1959,1968 **** ---- 1979,2067 ---- - posix_forkpty(PyObject *self, PyObject *args) - { - int master_fd, pid; -+ #if defined(sun) -+ int slave; -+ char * slave_name; -+ void *sig_saved; -+ int fd; -+ #endif - - if (!PyArg_ParseTuple(args, ":forkpty")) - return NULL; -+ #if defined(sun) -+ master_fd = open("/dev/ptmx", O_RDWR|O_NOCTTY); /* open master */ -+ sig_saved = signal(SIGCHLD, SIG_DFL); -+ grantpt(master_fd); /* change permission of slave */ -+ unlockpt(master_fd); /* unlock slave */ -+ signal(SIGCHLD,sig_saved); -+ slave_name = ptsname(master_fd); /* get name of slave */ -+ slave = open(slave_name, O_RDWR); /* open slave */ -+ ioctl(slave, I_PUSH, "ptem"); /* push ptem */ -+ ioctl(slave, I_PUSH, "ldterm"); /* push ldterm*/ -+ ioctl(slave, I_PUSH, "ttcompat"); /* push ttcompat*/ -+ if (master_fd < 0 || slave < 0) -+ { -+ return posix_error(); -+ } -+ switch (pid = fork()) { -+ case -1: -+ return posix_error(); -+ case 0: -+ /* First disconnect from the old controlling tty. */ -+ #ifdef TIOCNOTTY -+ fd = open("/dev/tty", O_RDWR | O_NOCTTY); -+ if (fd >= 0) { -+ (void) ioctl(fd, TIOCNOTTY, NULL); -+ close(fd); -+ } -+ #endif /* TIOCNOTTY */ -+ if (setsid() < 0) -+ return posix_error(); -+ -+ /* -+ * Verify that we are successfully disconnected from the controlling -+ * tty. -+ */ -+ fd = open("/dev/tty", O_RDWR | O_NOCTTY); -+ if (fd >= 0) { -+ return posix_error(); -+ close(fd); -+ } -+ /* Make it our controlling tty. */ -+ #ifdef TIOCSCTTY -+ if (ioctl(slave, TIOCSCTTY, NULL) < 0) -+ return posix_error(); -+ #endif /* TIOCSCTTY */ -+ fd = open(slave_name, O_RDWR); -+ if (fd < 0) { -+ return posix_error(); -+ } else { -+ close(fd); -+ } -+ /* Verify that we now have a controlling tty. */ -+ fd = open("/dev/tty", O_WRONLY); -+ if (fd < 0) -+ return posix_error(); -+ else { -+ close(fd); -+ } -+ (void) close(master_fd); -+ (void) dup2(slave, 0); -+ (void) dup2(slave, 1); -+ (void) dup2(slave, 2); -+ if (slave > 2) -+ (void) close(slave); -+ pid = 0; -+ break; -+ defautlt: -+ /* -+ * parent -+ */ -+ (void) close(slave); -+ } -+ #else - pid = forkpty(&master_fd, NULL, NULL, NULL); -+ #endif - if (pid == -1) - return posix_error(); - if (pid == 0) -*************** -*** 5607,5616 **** - #ifdef HAVE_FORK - {"fork", posix_fork, METH_VARARGS, posix_fork__doc__}, - #endif /* HAVE_FORK */ -! #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) - {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__}, - #endif /* HAVE_OPENPTY || HAVE__GETPTY */ -! #ifdef HAVE_FORKPTY - {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__}, - #endif /* HAVE_FORKPTY */ - #ifdef HAVE_GETEGID ---- 5706,5715 ---- - #ifdef HAVE_FORK - {"fork", posix_fork, METH_VARARGS, posix_fork__doc__}, - #endif /* HAVE_FORK */ -! #if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(sun) - {"openpty", posix_openpty, METH_VARARGS, posix_openpty__doc__}, - #endif /* HAVE_OPENPTY || HAVE__GETPTY */ -! #if defined(HAVE_FORKPTY) || defined(sun) - {"forkpty", posix_forkpty, METH_VARARGS, posix_forkpty__doc__}, - #endif /* HAVE_FORKPTY */ - #ifdef HAVE_GETEGID diff --git a/pexpect/pexpect.py b/pexpect/pexpect.py deleted file mode 100644 index b273bca..0000000 --- a/pexpect/pexpect.py +++ /dev/null @@ -1,1952 +0,0 @@ -'''Pexpect is a Python module for spawning child applications and controlling -them automatically. Pexpect can be used for automating interactive applications -such as ssh, ftp, passwd, telnet, etc. It can be used to a automate setup -scripts for duplicating software package installations on different servers. It -can be used for automated software testing. Pexpect is in the spirit of Don -Libes' Expect, but Pexpect is pure Python. Other Expect-like modules for Python -require TCL and Expect or require C extensions to be compiled. Pexpect does not -use C, Expect, or TCL extensions. It should work on any platform that supports -the standard Python pty module. The Pexpect interface focuses on ease of use so -that simple tasks are easy. - -There are two main interfaces to the Pexpect system; these are the function, -run() and the class, spawn. The spawn class is more powerful. The run() -function is simpler than spawn, and is good for quickly calling program. When -you call the run() function it executes a given program and then returns the -output. This is a handy replacement for os.system(). - -For example:: - - pexpect.run('ls -la') - -The spawn class is the more powerful interface to the Pexpect system. You can -use this to spawn a child program then interact with it by sending input and -expecting responses (waiting for patterns in the child's output). - -For example:: - - child = pexpect.spawn('scp foo user@example.com:.') - child.expect('Password:') - child.sendline(mypassword) - -This works even for commands that ask for passwords or other input outside of -the normal stdio streams. For example, ssh reads input directly from the TTY -device which bypasses stdin. - -Credits: Noah Spurrier, Richard Holden, Marco Molteni, Kimberley Burchett, -Robert Stone, Hartmut Goebel, Chad Schroeder, Erick Tryzelaar, Dave Kirby, Ids -vander Molen, George Todd, Noel Taylor, Nicolas D. Cesar, Alexander Gattin, -Jacques-Etienne Baudoux, Geoffrey Marshall, Francisco Lourenco, Glen Mabey, -Karthik Gurusamy, Fernando Perez, Corey Minyard, Jon Cohen, Guillaume -Chazarain, Andrew Ryan, Nick Craig-Wood, Andrew Stone, Jorgen Grahn, John -Spiegel, Jan Grant, and Shane Kerr. Let me know if I forgot anyone. - -Pexpect is free, open source, and all that good stuff. -http://pexpect.sourceforge.net/ - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -try: - import os - import sys - import time - import select - import string - import re - import struct - import resource - import types - import pty - import tty - import termios - import fcntl - import errno - import traceback - import signal -except ImportError, e: - raise ImportError(str(e) + ''' - -A critical module was not found. Probably this operating system does not -support it. Pexpect is intended for UNIX-like operating systems.''') - -__version__ = '2.6' -__revision__ = '1' -__all__ = ['ExceptionPexpect', 'EOF', 'TIMEOUT', 'spawn', 'run', 'which', - 'split_command_line', '__version__', '__revision__'] - - -# Exception classes used by this module. -class ExceptionPexpect(Exception): - - '''Base class for all exceptions raised by this module. - ''' - - def __init__(self, value): - - self.value = value - - def __str__(self): - - return str(self.value) - - def get_trace(self): - - '''This returns an abbreviated stack trace with lines that only concern - the caller. In other words, the stack trace inside the Pexpect module - is not included. ''' - - tblist = traceback.extract_tb(sys.exc_info()[2]) - #tblist = filter(self.__filter_not_pexpect, tblist) - tblist = [item for item in tblist if self.__filter_not_pexpect(item)] - tblist = traceback.format_list(tblist) - return ''.join(tblist) - - def __filter_not_pexpect(self, trace_list_item): - - '''This returns True if list item 0 the string 'pexpect.py' in it. ''' - - if trace_list_item[0].find('pexpect.py') == -1: - return True - else: - return False - - -class EOF(ExceptionPexpect): - - '''Raised when EOF is read from a child. - This usually means the child has exited.''' - - -class TIMEOUT(ExceptionPexpect): - - '''Raised when a read time exceeds the timeout. ''' - -##class TIMEOUT_PATTERN(TIMEOUT): -## '''Raised when the pattern match time exceeds the timeout. -## This is different than a read TIMEOUT because the child process may -## give output, thus never give a TIMEOUT, but the output -## may never match a pattern. -## ''' -##class MAXBUFFER(ExceptionPexpect): -## '''Raised when a buffer fills before matching an expected pattern.''' - - -def run(command, timeout=-1, withexitstatus=False, events=None, - extra_args=None, logfile=None, cwd=None, env=None): - - ''' - This function runs the given command; waits for it to finish; then - returns all output as a string. STDERR is included in output. If the full - path to the command is not given then the path is searched. - - Note that lines are terminated by CR/LF (\\r\\n) combination even on - UNIX-like systems because this is the standard for pseudottys. If you set - 'withexitstatus' to true, then run will return a tuple of (command_output, - exitstatus). If 'withexitstatus' is false then this returns just - command_output. - - The run() function can often be used instead of creating a spawn instance. - For example, the following code uses spawn:: - - from pexpect import * - child = spawn('scp foo user@example.com:.') - child.expect('(?i)password') - child.sendline(mypassword) - - The previous code can be replace with the following:: - - from pexpect import * - run('scp foo user@example.com:.', events={'(?i)password': mypassword}) - - Examples - ======== - - Start the apache daemon on the local machine:: - - from pexpect import * - run("/usr/local/apache/bin/apachectl start") - - Check in a file using SVN:: - - from pexpect import * - run("svn ci -m 'automatic commit' my_file.py") - - Run a command and capture exit status:: - - from pexpect import * - (command_output, exitstatus) = run('ls -l /bin', withexitstatus=1) - - Tricky Examples - =============== - - The following will run SSH and execute 'ls -l' on the remote machine. The - password 'secret' will be sent if the '(?i)password' pattern is ever seen:: - - run("ssh username@machine.example.com 'ls -l'", - events={'(?i)password':'secret\\n'}) - - This will start mencoder to rip a video from DVD. This will also display - progress ticks every 5 seconds as it runs. For example:: - - from pexpect import * - def print_ticks(d): - print d['event_count'], - run("mencoder dvd://1 -o video.avi -oac copy -ovc copy", - events={TIMEOUT:print_ticks}, timeout=5) - - The 'events' argument should be a dictionary of patterns and responses. - Whenever one of the patterns is seen in the command out run() will send the - associated response string. Note that you should put newlines in your - string if Enter is necessary. The responses may also contain callback - functions. Any callback is function that takes a dictionary as an argument. - The dictionary contains all the locals from the run() function, so you can - access the child spawn object or any other variable defined in run() - (event_count, child, and extra_args are the most useful). A callback may - return True to stop the current run process otherwise run() continues until - the next event. A callback may also return a string which will be sent to - the child. 'extra_args' is not used by directly run(). It provides a way to - pass data to a callback function through run() through the locals - dictionary passed to a callback. ''' - - if timeout == -1: - child = spawn(command, maxread=2000, logfile=logfile, cwd=cwd, env=env) - else: - child = spawn(command, timeout=timeout, maxread=2000, logfile=logfile, - cwd=cwd, env=env) - if events is not None: - patterns = list(events.keys()) - responses = list(events.values()) - else: - # This assumes EOF or TIMEOUT will eventually cause run to terminate. - patterns = None - responses = None - child_result_list = [] - event_count = 0 - while True: - try: - index = child.expect(patterns) - if type(child.after) in types.StringTypes: - child_result_list.append(child.before + child.after) - else: - # child.after may have been a TIMEOUT or EOF, - # which we don't want appended to the list. - child_result_list.append(child.before) - if type(responses[index]) in types.StringTypes: - child.send(responses[index]) - elif isinstance(responses[index], types.FunctionType): - callback_result = responses[index](locals()) - sys.stdout.flush() - if type(callback_result) in types.StringTypes: - child.send(callback_result) - elif callback_result: - break - else: - raise TypeError('The callback must be a string or function.') - event_count = event_count + 1 - except TIMEOUT: - child_result_list.append(child.before) - break - except EOF: - child_result_list.append(child.before) - break - child_result = ''.join(child_result_list) - if withexitstatus: - child.close() - return (child_result, child.exitstatus) - else: - return child_result - - -class spawn(object): - - '''This is the main class interface for Pexpect. Use this class to start - and control child applications. ''' - - def __init__(self, command, args=[], timeout=30, maxread=2000, - searchwindowsize=None, logfile=None, cwd=None, env=None): - - '''This is the constructor. The command parameter may be a string that - includes a command and any arguments to the command. For example:: - - child = pexpect.spawn('/usr/bin/ftp') - child = pexpect.spawn('/usr/bin/ssh user@example.com') - child = pexpect.spawn('ls -latr /tmp') - - You may also construct it with a list of arguments like so:: - - child = pexpect.spawn('/usr/bin/ftp', []) - child = pexpect.spawn('/usr/bin/ssh', ['user@example.com']) - child = pexpect.spawn('ls', ['-latr', '/tmp']) - - After this the child application will be created and will be ready to - talk to. For normal use, see expect() and send() and sendline(). - - Remember that Pexpect does NOT interpret shell meta characters such as - redirect, pipe, or wild cards (>, |, or *). This is a common mistake. - If you want to run a command and pipe it through another command then - you must also start a shell. For example:: - - child = pexpect.spawn('/bin/bash -c "ls -l | grep LOG > logs.txt"') - child.expect(pexpect.EOF) - - The second form of spawn (where you pass a list of arguments) is useful - in situations where you wish to spawn a command and pass it its own - argument list. This can make syntax more clear. For example, the - following is equivalent to the previous example:: - - shell_cmd = 'ls -l | grep LOG > logs.txt' - child = pexpect.spawn('/bin/bash', ['-c', shell_cmd]) - child.expect(pexpect.EOF) - - The maxread attribute sets the read buffer size. This is maximum number - of bytes that Pexpect will try to read from a TTY at one time. Setting - the maxread size to 1 will turn off buffering. Setting the maxread - value higher may help performance in cases where large amounts of - output are read back from the child. This feature is useful in - conjunction with searchwindowsize. - - The searchwindowsize attribute sets the how far back in the incomming - seach buffer Pexpect will search for pattern matches. Every time - Pexpect reads some data from the child it will append the data to the - incomming buffer. The default is to search from the beginning of the - imcomming buffer each time new data is read from the child. But this is - very inefficient if you are running a command that generates a large - amount of data where you want to match The searchwindowsize does not - effect the size of the incomming data buffer. You will still have - access to the full buffer after expect() returns. - - The logfile member turns on or off logging. All input and output will - be copied to the given file object. Set logfile to None to stop - logging. This is the default. Set logfile to sys.stdout to echo - everything to standard output. The logfile is flushed after each write. - - Example log input and output to a file:: - - child = pexpect.spawn('some_command') - fout = file('mylog.txt','w') - child.logfile = fout - - Example log to stdout:: - - child = pexpect.spawn('some_command') - child.logfile = sys.stdout - - The logfile_read and logfile_send members can be used to separately log - the input from the child and output sent to the child. Sometimes you - don't want to see everything you write to the child. You only want to - log what the child sends back. For example:: - - child = pexpect.spawn('some_command') - child.logfile_read = sys.stdout - - To separately log output sent to the child use logfile_send:: - - self.logfile_send = fout - - The delaybeforesend helps overcome a weird behavior that many users - were experiencing. The typical problem was that a user would expect() a - "Password:" prompt and then immediately call sendline() to send the - password. The user would then see that their password was echoed back - to them. Passwords don't normally echo. The problem is caused by the - fact that most applications print out the "Password" prompt and then - turn off stdin echo, but if you send your password before the - application turned off echo, then you get your password echoed. - Normally this wouldn't be a problem when interacting with a human at a - real keyboard. If you introduce a slight delay just before writing then - this seems to clear up the problem. This was such a common problem for - many users that I decided that the default pexpect behavior should be - to sleep just before writing to the child application. 1/20th of a - second (50 ms) seems to be enough to clear up the problem. You can set - delaybeforesend to 0 to return to the old behavior. Most Linux machines - don't like this to be below 0.03. I don't know why. - - Note that spawn is clever about finding commands on your path. - It uses the same logic that "which" uses to find executables. - - If you wish to get the exit status of the child you must call the - close() method. The exit or signal status of the child will be stored - in self.exitstatus or self.signalstatus. If the child exited normally - then exitstatus will store the exit return code and signalstatus will - be None. If the child was terminated abnormally with a signal then - signalstatus will store the signal value and exitstatus will be None. - If you need more detail you can also read the self.status member which - stores the status returned by os.waitpid. You can interpret this using - os.WIFEXITED/os.WEXITSTATUS or os.WIFSIGNALED/os.TERMSIG. ''' - - self.STDIN_FILENO = pty.STDIN_FILENO - self.STDOUT_FILENO = pty.STDOUT_FILENO - self.STDERR_FILENO = pty.STDERR_FILENO - self.stdin = sys.stdin - self.stdout = sys.stdout - self.stderr = sys.stderr - - self.searcher = None - self.ignorecase = False - self.before = None - self.after = None - self.match = None - self.match_index = None - self.terminated = True - self.exitstatus = None - self.signalstatus = None - # status returned by os.waitpid - self.status = None - self.flag_eof = False - self.pid = None - # the chile filedescriptor is initially closed - self.child_fd = -1 - self.timeout = timeout - self.delimiter = EOF - self.logfile = logfile - # input from child (read_nonblocking) - self.logfile_read = None - # output to send (send, sendline) - self.logfile_send = None - # max bytes to read at one time into buffer - self.maxread = maxread - # This is the read buffer. See maxread. - self.buffer = '' - # Data before searchwindowsize point is preserved, but not searched. - self.searchwindowsize = searchwindowsize - # Delay used before sending data to child. Time in seconds. - # Most Linux machines don't like this to be below 0.03 (30 ms). - self.delaybeforesend = 0.05 - # Used by close() to give kernel time to update process status. - # Time in seconds. - self.delayafterclose = 0.1 - # Used by terminate() to give kernel time to update process status. - # Time in seconds. - self.delayafterterminate = 0.1 - self.softspace = False - self.name = '<' + repr(self) + '>' - self.encoding = None - self.closed = True - self.cwd = cwd - self.env = env - # This flags if we are running on irix - self.__irix_hack = (sys.platform.lower().find('irix') >= 0) - # Solaris uses internal __fork_pty(). All others use pty.fork(). - if ((sys.platform.lower().find('solaris') >= 0) - or (sys.platform.lower().find('sunos5') >= 0)): - self.use_native_pty_fork = False - else: - self.use_native_pty_fork = True - - # Support subclasses that do not use command or args. - if command is None: - self.command = None - self.args = None - self.name = '<pexpect factory incomplete>' - else: - self._spawn(command, args) - - def __del__(self): - - '''This makes sure that no system resources are left open. Python only - garbage collects Python objects. OS file descriptors are not Python - objects, so they must be handled explicitly. If the child file - descriptor was opened outside of this class (passed to the constructor) - then this does not close it. ''' - - if not self.closed: - # It is possible for __del__ methods to execute during the - # teardown of the Python VM itself. Thus self.close() may - # trigger an exception because os.close may be None. - try: - self.close() - except: - pass - - def __str__(self): - - '''This returns a human-readable string that represents the state of - the object. ''' - - s = [] - s.append(repr(self)) - s.append('version: ' + __version__ + ' (' + __revision__ + ')') - s.append('command: ' + str(self.command)) - s.append('args: ' + str(self.args)) - s.append('searcher: ' + str(self.searcher)) - s.append('buffer (last 100 chars): ' + str(self.buffer)[-100:]) - s.append('before (last 100 chars): ' + str(self.before)[-100:]) - s.append('after: ' + str(self.after)) - s.append('match: ' + str(self.match)) - s.append('match_index: ' + str(self.match_index)) - s.append('exitstatus: ' + str(self.exitstatus)) - s.append('flag_eof: ' + str(self.flag_eof)) - s.append('pid: ' + str(self.pid)) - s.append('child_fd: ' + str(self.child_fd)) - s.append('closed: ' + str(self.closed)) - s.append('timeout: ' + str(self.timeout)) - s.append('delimiter: ' + str(self.delimiter)) - s.append('logfile: ' + str(self.logfile)) - s.append('logfile_read: ' + str(self.logfile_read)) - s.append('logfile_send: ' + str(self.logfile_send)) - s.append('maxread: ' + str(self.maxread)) - s.append('ignorecase: ' + str(self.ignorecase)) - s.append('searchwindowsize: ' + str(self.searchwindowsize)) - s.append('delaybeforesend: ' + str(self.delaybeforesend)) - s.append('delayafterclose: ' + str(self.delayafterclose)) - s.append('delayafterterminate: ' + str(self.delayafterterminate)) - return '\n'.join(s) - - def _spawn(self, command, args=[]): - - '''This starts the given command in a child process. This does all the - fork/exec type of stuff for a pty. This is called by __init__. If args - is empty then command will be parsed (split on spaces) and args will be - set to parsed arguments. ''' - - # The pid and child_fd of this object get set by this method. - # Note that it is difficult for this method to fail. - # You cannot detect if the child process cannot start. - # So the only way you can tell if the child process started - # or not is to try to read from the file descriptor. If you get - # EOF immediately then it means that the child is already dead. - # That may not necessarily be bad because you may have spawned a child - # that performs some task; creates no stdout output; and then dies. - - # If command is an int type then it may represent a file descriptor. - if isinstance(command, type(0)): - raise ExceptionPexpect('Command is an int type. ' + - 'If this is a file descriptor then maybe you want to ' + - 'use fdpexpect.fdspawn which takes an existing ' + - 'file descriptor instead of a command string.') - - if not isinstance(args, type([])): - raise TypeError('The argument, args, must be a list.') - - if args == []: - self.args = split_command_line(command) - self.command = self.args[0] - else: - # Make a shallow copy of the args list. - self.args = args[:] - self.args.insert(0, command) - self.command = command - - command_with_path = which(self.command) - if command_with_path is None: - raise ExceptionPexpect('The command was not found or was not ' + - 'executable: %s.' % self.command) - self.command = command_with_path - self.args[0] = self.command - - self.name = '<' + ' '.join(self.args) + '>' - - assert self.pid is None, 'The pid member must be None.' - assert self.command is not None, 'The command member must not be None.' - - if self.use_native_pty_fork: - try: - self.pid, self.child_fd = pty.fork() - except OSError, e: - raise ExceptionPexpect('pty.fork() failed: ' + str(e)) - else: - # Use internal __fork_pty - self.pid, self.child_fd = self.__fork_pty() - - if self.pid == 0: - # Child - try: - # used by setwinsize() - self.child_fd = sys.stdout.fileno() - self.setwinsize(24, 80) - except: - # Some platforms do not like setwinsize (Cygwin). - # This will cause problem when running applications that - # are very picky about window size. - # This is a serious limitation, but not a show stopper. - pass - # Do not allow child to inherit open file descriptors from parent. - max_fd = resource.getrlimit(resource.RLIMIT_NOFILE)[0] - for i in range(3, max_fd): - try: - os.close(i) - except OSError: - pass - - # I don't know why this works, but ignoring SIGHUP fixes a - # problem when trying to start a Java daemon with sudo - # (specifically, Tomcat). - signal.signal(signal.SIGHUP, signal.SIG_IGN) - - if self.cwd is not None: - os.chdir(self.cwd) - if self.env is None: - os.execv(self.command, self.args) - else: - os.execvpe(self.command, self.args, self.env) - - # Parent - self.terminated = False - self.closed = False - - def __fork_pty(self): - - '''This implements a substitute for the forkpty system call. This - should be more portable than the pty.fork() function. Specifically, - this should work on Solaris. - - Modified 10.06.05 by Geoff Marshall: Implemented __fork_pty() method to - resolve the issue with Python's pty.fork() not supporting Solaris, - particularly ssh. Based on patch to posixmodule.c authored by Noah - Spurrier:: - - http://mail.python.org/pipermail/python-dev/2003-May/035281.html - - ''' - - parent_fd, child_fd = os.openpty() - if parent_fd < 0 or child_fd < 0: - raise ExceptionPexpect("Could not open with os.openpty().") - - pid = os.fork() - if pid < 0: - raise ExceptionPexpect("Failed os.fork().") - elif pid == 0: - # Child. - os.close(parent_fd) - self.__pty_make_controlling_tty(child_fd) - - os.dup2(child_fd, 0) - os.dup2(child_fd, 1) - os.dup2(child_fd, 2) - - if child_fd > 2: - os.close(child_fd) - else: - # Parent. - os.close(child_fd) - - return pid, parent_fd - - def __pty_make_controlling_tty(self, tty_fd): - - '''This makes the pseudo-terminal the controlling tty. This should be - more portable than the pty.fork() function. Specifically, this should - work on Solaris. ''' - - child_name = os.ttyname(tty_fd) - - # Disconnect from controlling tty. Harmless if not already connected. - try: - fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY) - if fd >= 0: - os.close(fd) - except: - # Already disconnected. This happens if running inside cron. - pass - - os.setsid() - - # Verify we are disconnected from controlling tty - # by attempting to open it again. - try: - fd = os.open("/dev/tty", os.O_RDWR | os.O_NOCTTY) - if fd >= 0: - os.close(fd) - raise ExceptionPexpect('Failed to disconnect from ' + - 'controlling tty. It is still possible to open /dev/tty.') - except: - # Good! We are disconnected from a controlling tty. - pass - - # Verify we can open child pty. - fd = os.open(child_name, os.O_RDWR) - if fd < 0: - raise ExceptionPexpect("Could not open child pty, " + child_name) - else: - os.close(fd) - - # Verify we now have a controlling tty. - fd = os.open("/dev/tty", os.O_WRONLY) - if fd < 0: - raise ExceptionPexpect("Could not open controlling tty, /dev/tty") - else: - os.close(fd) - - def fileno(self): - - '''This returns the file descriptor of the pty for the child. - ''' - - return self.child_fd - - def close(self, force=True): - - '''This closes the connection with the child application. Note that - calling close() more than once is valid. This emulates standard Python - behavior with files. Set force to True if you want to make sure that - the child is terminated (SIGKILL is sent if the child ignores SIGHUP - and SIGINT). ''' - - if not self.closed: - self.flush() - os.close(self.child_fd) - # Give kernel time to update process status. - time.sleep(self.delayafterclose) - if self.isalive(): - if not self.terminate(force): - raise ExceptionPexpect('Could not terminate the child.') - self.child_fd = -1 - self.closed = True - #self.pid = None - - def flush(self): - - '''This does nothing. It is here to support the interface for a - File-like object. ''' - - pass - - def isatty(self): - - '''This returns True if the file descriptor is open and connected to a - tty(-like) device, else False. ''' - - return os.isatty(self.child_fd) - - def waitnoecho(self, timeout=-1): - - '''This waits until the terminal ECHO flag is set False. This returns - True if the echo mode is off. This returns False if the ECHO flag was - not set False before the timeout. This can be used to detect when the - child is waiting for a password. Usually a child application will turn - off echo mode when it is waiting for the user to enter a password. For - example, instead of expecting the "password:" prompt you can wait for - the child to set ECHO off:: - - p = pexpect.spawn('ssh user@example.com') - p.waitnoecho() - p.sendline(mypassword) - - If timeout==-1 then this method will use the value in self.timeout. - If timeout==None then this method to block until ECHO flag is False. - ''' - - if timeout == -1: - timeout = self.timeout - if timeout is not None: - end_time = time.time() + timeout - while True: - if not self.getecho(): - return True - if timeout < 0 and timeout is not None: - return False - if timeout is not None: - timeout = end_time - time.time() - time.sleep(0.1) - - def getecho(self): - - '''This returns the terminal echo mode. This returns True if echo is - on or False if echo is off. Child applications that are expecting you - to enter a password often set ECHO False. See waitnoecho(). ''' - - attr = termios.tcgetattr(self.child_fd) - if attr[3] & termios.ECHO: - return True - return False - - def setecho(self, state): - - '''This sets the terminal echo mode on or off. Note that anything the - child sent before the echo will be lost, so you should be sure that - your input buffer is empty before you call setecho(). For example, the - following will work as expected:: - - p = pexpect.spawn('cat') # Echo is on by default. - p.sendline('1234') # We expect see this twice from the child... - p.expect(['1234']) # ... once from the tty echo... - p.expect(['1234']) # ... and again from cat itself. - p.setecho(False) # Turn off tty echo - p.sendline('abcd') # We will set this only once (echoed by cat). - p.sendline('wxyz') # We will set this only once (echoed by cat) - p.expect(['abcd']) - p.expect(['wxyz']) - - The following WILL NOT WORK because the lines sent before the setecho - will be lost:: - - p = pexpect.spawn('cat') - p.sendline('1234') - p.setecho(False) # Turn off tty echo - p.sendline('abcd') # We will set this only once (echoed by cat). - p.sendline('wxyz') # We will set this only once (echoed by cat) - p.expect(['1234']) - p.expect(['1234']) - p.expect(['abcd']) - p.expect(['wxyz']) - ''' - - self.child_fd - attr = termios.tcgetattr(self.child_fd) - if state: - attr[3] = attr[3] | termios.ECHO - else: - attr[3] = attr[3] & ~termios.ECHO - # I tried TCSADRAIN and TCSAFLUSH, but - # these were inconsistent and blocked on some platforms. - # TCSADRAIN would probably be ideal if it worked. - termios.tcsetattr(self.child_fd, termios.TCSANOW, attr) - - def read_nonblocking(self, size=1, timeout=-1): - - '''This reads at most size characters from the child application. It - includes a timeout. If the read does not complete within the timeout - period then a TIMEOUT exception is raised. If the end of file is read - then an EOF exception will be raised. If a log file was set using - setlog() then all data will also be written to the log file. - - If timeout is None then the read may block indefinitely. - If timeout is -1 then the self.timeout value is used. If timeout is 0 - then the child is polled and if there is no data immediately ready - then this will raise a TIMEOUT exception. - - The timeout refers only to the amount of time to read at least one - character. This is not effected by the 'size' parameter, so if you call - read_nonblocking(size=100, timeout=30) and only one character is - available right away then one character will be returned immediately. - It will not wait for 30 seconds for another 99 characters to come in. - - This is a wrapper around os.read(). It uses select.select() to - implement the timeout. ''' - - if self.closed: - raise ValueError('I/O operation on closed file.') - - if timeout == -1: - timeout = self.timeout - - # Note that some systems such as Solaris do not give an EOF when - # the child dies. In fact, you can still try to read - # from the child_fd -- it will block forever or until TIMEOUT. - # For this case, I test isalive() before doing any reading. - # If isalive() is false, then I pretend that this is the same as EOF. - if not self.isalive(): - # timeout of 0 means "poll" - r, w, e = self.__select([self.child_fd], [], [], 0) - if not r: - self.flag_eof = True - raise EOF('End Of File (EOF). Braindead platform.') - elif self.__irix_hack: - # Irix takes a long time before it realizes a child was terminated. - # FIXME So does this mean Irix systems are forced to always have - # FIXME a 2 second delay when calling read_nonblocking? That sucks. - r, w, e = self.__select([self.child_fd], [], [], 2) - if not r and not self.isalive(): - self.flag_eof = True - raise EOF('End Of File (EOF). Slow platform.') - - r, w, e = self.__select([self.child_fd], [], [], timeout) - - if not r: - if not self.isalive(): - # Some platforms, such as Irix, will claim that their - # processes are alive; timeout on the select; and - # then finally admit that they are not alive. - self.flag_eof = True - raise EOF('End of File (EOF). Very slow platform.') - else: - raise TIMEOUT('Timeout exceeded.') - - if self.child_fd in r: - try: - s = os.read(self.child_fd, size) - except OSError: - # Linux does this - self.flag_eof = True - raise EOF('End Of File (EOF). Exception style platform.') - if s == '': - # BSD style - self.flag_eof = True - raise EOF('End Of File (EOF). Empty string style platform.') - if self.logfile is not None: - self.logfile.write(s) - self.logfile.flush() - if self.logfile_read is not None: - self.logfile_read.write(s) - self.logfile_read.flush() - return s - - raise ExceptionPexpect('Reached an unexpected state.') - - def read(self, size=-1): - - '''This reads at most "size" bytes from the file (less if the read hits - EOF before obtaining size bytes). If the size argument is negative or - omitted, read all data until EOF is reached. The bytes are returned as - a string object. An empty string is returned when EOF is encountered - immediately. ''' - - if size == 0: - return '' - if size < 0: - # delimiter default is EOF - self.expect(self.delimiter) - return self.before - - # I could have done this more directly by not using expect(), but - # I deliberately decided to couple read() to expect() so that - # I would catch any bugs early and ensure consistant behavior. - # It's a little less efficient, but there is less for me to - # worry about if I have to later modify read() or expect(). - # Note, it's OK if size==-1 in the regex. That just means it - # will never match anything in which case we stop only on EOF. - cre = re.compile('.{%d}' % size, re.DOTALL) - # delimiter default is EOF - index = self.expect([cre, self.delimiter]) - if index == 0: - ### FIXME self.before should be ''. Should I assert this? - return self.after - return self.before - - def readline(self, size=-1): - - '''This reads and returns one entire line. The newline at the end of - line is returned as part of the string, unless the file ends without a - newline. An empty string is returned if EOF is encountered immediately. - This looks for a newline as a CR/LF pair (\\r\\n) even on UNIX because - this is what the pseudotty device returns. So contrary to what you may - expect you will receive newlines as \\r\\n. - - If the size argument is 0 then an empty string is returned. In all - other cases the size argument is ignored, which is not standard - behavior for a file-like object. ''' - - if size == 0: - return '' - # delimiter default is EOF - index = self.expect(['\r\n', self.delimiter]) - if index == 0: - return self.before + '\r\n' - else: - return self.before - - def __iter__(self): - - '''This is to support iterators over a file-like object. - ''' - - #return iter(self) - return iter(self.readline, '') - -# def __next__(self): -# -# '''This is to support iterators over a file-like object. -# ''' -# -# result = self.readline() -# if result == '': -# raise StopIteration -# return result - - def readlines(self, sizehint=-1): - - '''This reads until EOF using readline() and returns a list containing - the lines thus read. The optional 'sizehint' argument is ignored. - Remember, because this reads until EOF that means the child - process should have closed its stdout. If you run this method on - a child that is still running with its stdout open then this - method will block until it timesout.''' - - lines = [] - while True: - line = self.readline() - if not line: - break - lines.append(line) - return lines - - def write(self, s): - - '''This is similar to send() except that there is no return value. - ''' - - self.send(s) - - def writelines(self, sequence): - - '''This calls write() for each element in the sequence. The sequence - can be any iterable object producing strings, typically a list of - strings. This does not add line separators There is no return value. - ''' - - for s in sequence: - self.write(s) - - def send(self, s): - - '''This sends a string to the child process. This returns the number of - bytes written. If a log file was set then the data is also written to - the log. ''' - - time.sleep(self.delaybeforesend) - if self.logfile is not None: - self.logfile.write(s) - self.logfile.flush() - if self.logfile_send is not None: - self.logfile_send.write(s) - self.logfile_send.flush() - c = os.write(self.child_fd, s.encode("utf-8")) - return c - - def sendline(self, s=''): - - '''This is like send(), but it adds a linefeed (os.linesep). This - returns the number of bytes written. ''' - - n = self.send(s) - n = n + self.send(os.linesep) - return n - - def sendcontrol(self, char): - - '''This sends a control character to the child such as Ctrl-C or - Ctrl-D. For example, to send a Ctrl-G (ASCII 7):: - - child.sendcontrol('g') - - See also, sendintr() and sendeof(). - ''' - - char = char.lower() - a = ord(char) - if a >= 97 and a <= 122: - a = a - ord('a') + 1 - return self.send(chr(a)) - d = {'@': 0, '`': 0, - '[': 27, '{': 27, - '\\': 28, '|': 28, - ']': 29, '}': 29, - '^': 30, '~': 30, - '_': 31, - '?': 127} - if char not in d: - return 0 - return self.send(chr(d[char])) - - def sendeof(self): - - '''This sends an EOF to the child. This sends a character which causes - the pending parent output buffer to be sent to the waiting child - program without waiting for end-of-line. If it is the first character - of the line, the read() in the user program returns 0, which signifies - end-of-file. This means to work as expected a sendeof() has to be - called at the beginning of a line. This method does not send a newline. - It is the responsibility of the caller to ensure the eof is sent at the - beginning of a line. ''' - - ### Hmmm... how do I send an EOF? - ###C if ((m = write(pty, *buf, p - *buf)) < 0) - ###C return (errno == EWOULDBLOCK) ? n : -1; - #fd = sys.stdin.fileno() - #old = termios.tcgetattr(fd) # remember current state - #attr = termios.tcgetattr(fd) - #attr[3] = attr[3] | termios.ICANON # ICANON must be set to see EOF - #try: # use try/finally to ensure state gets restored - # termios.tcsetattr(fd, termios.TCSADRAIN, attr) - # if hasattr(termios, 'CEOF'): - # os.write(self.child_fd, '%c' % termios.CEOF) - # else: - # # Silly platform does not define CEOF so assume CTRL-D - # os.write(self.child_fd, '%c' % 4) - #finally: # restore state - # termios.tcsetattr(fd, termios.TCSADRAIN, old) - if hasattr(termios, 'VEOF'): - char = termios.tcgetattr(self.child_fd)[6][termios.VEOF] - else: - # platform does not define VEOF so assume CTRL-D - char = chr(4) - self.send(char) - - def sendintr(self): - - '''This sends a SIGINT to the child. It does not require - the SIGINT to be the first character on a line. ''' - - if hasattr(termios, 'VINTR'): - char = termios.tcgetattr(self.child_fd)[6][termios.VINTR] - else: - # platform does not define VINTR so assume CTRL-C - char = chr(3) - self.send(char) - - def eof(self): - - '''This returns True if the EOF exception was ever raised. - ''' - - return self.flag_eof - - def terminate(self, force=False): - - '''This forces a child process to terminate. It starts nicely with - SIGHUP and SIGINT. If "force" is True then moves onto SIGKILL. This - returns True if the child was terminated. This returns False if the - child could not be terminated. ''' - - if not self.isalive(): - return True - try: - self.kill(signal.SIGHUP) - time.sleep(self.delayafterterminate) - if not self.isalive(): - return True - self.kill(signal.SIGCONT) - time.sleep(self.delayafterterminate) - if not self.isalive(): - return True - self.kill(signal.SIGINT) - time.sleep(self.delayafterterminate) - if not self.isalive(): - return True - if force: - self.kill(signal.SIGKILL) - time.sleep(self.delayafterterminate) - if not self.isalive(): - return True - else: - return False - return False - except OSError: - # I think there are kernel timing issues that sometimes cause - # this to happen. I think isalive() reports True, but the - # process is dead to the kernel. - # Make one last attempt to see if the kernel is up to date. - time.sleep(self.delayafterterminate) - if not self.isalive(): - return True - else: - return False - - def wait(self): - - '''This waits until the child exits. This is a blocking call. This will - not read any data from the child, so this will block forever if the - child has unread output and has terminated. In other words, the child - may have printed output then called exit(), but, the child is - technically still alive until its output is read by the parent. ''' - - if self.isalive(): - pid, status = os.waitpid(self.pid, 0) - else: - raise ExceptionPexpect('Cannot wait for dead child process.') - self.exitstatus = os.WEXITSTATUS(status) - if os.WIFEXITED(status): - self.status = status - self.exitstatus = os.WEXITSTATUS(status) - self.signalstatus = None - self.terminated = True - elif os.WIFSIGNALED(status): - self.status = status - self.exitstatus = None - self.signalstatus = os.WTERMSIG(status) - self.terminated = True - elif os.WIFSTOPPED(status): - # You can't call wait() on a child process in the stopped state. - raise ExceptionPexpect('Called wait() on a stopped child ' + - 'process. This is not supported. Is some other ' + - 'process attempting job control with our child pid?') - return self.exitstatus - - def isalive(self): - - '''This tests if the child process is running or not. This is - non-blocking. If the child was terminated then this will read the - exitstatus or signalstatus of the child. This returns True if the child - process appears to be running or False if not. It can take literally - SECONDS for Solaris to return the right status. ''' - - if self.terminated: - return False - - if self.flag_eof: - # This is for Linux, which requires the blocking form - # of waitpid to # get status of a defunct process. - # This is super-lame. The flag_eof would have been set - # in read_nonblocking(), so this should be safe. - waitpid_options = 0 - else: - waitpid_options = os.WNOHANG - - try: - pid, status = os.waitpid(self.pid, waitpid_options) - except OSError, e: - # No child processes - if e[0] == errno.ECHILD: - raise ExceptionPexpect('isalive() encountered condition ' + - 'where "terminated" is 0, but there was no child ' + - 'process. Did someone else call waitpid() ' + - 'on our process?') - else: - raise e - - # I have to do this twice for Solaris. - # I can't even believe that I figured this out... - # If waitpid() returns 0 it means that no child process - # wishes to report, and the value of status is undefined. - if pid == 0: - try: - ### os.WNOHANG) # Solaris! - pid, status = os.waitpid(self.pid, waitpid_options) - except OSError, e: - # This should never happen... - if e[0] == errno.ECHILD: - raise ExceptionPexpect('isalive() encountered condition ' + - 'that should never happen. There was no child ' + - 'process. Did someone else call waitpid() ' + - 'on our process?') - else: - raise e - - # If pid is still 0 after two calls to waitpid() then the process - # really is alive. This seems to work on all platforms, except for - # Irix which seems to require a blocking call on waitpid or select, - # so I let read_nonblocking take care of this situation - # (unfortunately, this requires waiting through the timeout). - if pid == 0: - return True - - if pid == 0: - return True - - if os.WIFEXITED(status): - self.status = status - self.exitstatus = os.WEXITSTATUS(status) - self.signalstatus = None - self.terminated = True - elif os.WIFSIGNALED(status): - self.status = status - self.exitstatus = None - self.signalstatus = os.WTERMSIG(status) - self.terminated = True - elif os.WIFSTOPPED(status): - raise ExceptionPexpect('isalive() encountered condition ' + - 'where child process is stopped. This is not ' + - 'supported. Is some other process attempting ' + - 'job control with our child pid?') - return False - - def kill(self, sig): - - '''This sends the given signal to the child application. In keeping - with UNIX tradition it has a misleading name. It does not necessarily - kill the child unless you send the right signal. ''' - - # Same as os.kill, but the pid is given for you. - if self.isalive(): - os.kill(self.pid, sig) - - def compile_pattern_list(self, patterns): - - '''This compiles a pattern-string or a list of pattern-strings. - Patterns must be a StringType, EOF, TIMEOUT, SRE_Pattern, or a list of - those. Patterns may also be None which results in an empty list (you - might do this if waiting for an EOF or TIMEOUT condition without - expecting any pattern). - - This is used by expect() when calling expect_list(). Thus expect() is - nothing more than:: - - cpl = self.compile_pattern_list(pl) - return self.expect_list(cpl, timeout) - - If you are using expect() within a loop it may be more - efficient to compile the patterns first and then call expect_list(). - This avoid calls in a loop to compile_pattern_list():: - - cpl = self.compile_pattern_list(my_pattern) - while some_condition: - ... - i = self.expect_list(clp, timeout) - ... - ''' - - if patterns is None: - return [] - if not isinstance(patterns, list): - patterns = [patterns] - - # Allow dot to match \n - compile_flags = re.DOTALL - if self.ignorecase: - compile_flags = compile_flags | re.IGNORECASE - compiled_pattern_list = [] - for p in patterns: - if type(p) in types.StringTypes: - compiled_pattern_list.append(re.compile(p, compile_flags)) - elif p is EOF: - compiled_pattern_list.append(EOF) - elif p is TIMEOUT: - compiled_pattern_list.append(TIMEOUT) - elif isinstance(p, type(re.compile(''))): - compiled_pattern_list.append(p) - else: - raise TypeError('Argument must be one of StringTypes, ' + - 'EOF, TIMEOUT, SRE_Pattern, or a list of those ' + - 'type. %s' % str(type(p))) - - return compiled_pattern_list - - def expect(self, pattern, timeout=-1, searchwindowsize=-1): - - '''This seeks through the stream until a pattern is matched. The - pattern is overloaded and may take several types. The pattern can be a - StringType, EOF, a compiled re, or a list of any of those types. - Strings will be compiled to re types. This returns the index into the - pattern list. If the pattern was not a list this returns index 0 on a - successful match. This may raise exceptions for EOF or TIMEOUT. To - avoid the EOF or TIMEOUT exceptions add EOF or TIMEOUT to the pattern - list. That will cause expect to match an EOF or TIMEOUT condition - instead of raising an exception. - - If you pass a list of patterns and more than one matches, the first - match in the stream is chosen. If more than one pattern matches at that - point, the leftmost in the pattern list is chosen. For example:: - - # the input is 'foobar' - index = p.expect(['bar', 'foo', 'foobar']) - # returns 1('foo') even though 'foobar' is a "better" match - - Please note, however, that buffering can affect this behavior, since - input arrives in unpredictable chunks. For example:: - - # the input is 'foobar' - index = p.expect(['foobar', 'foo']) - # returns 0('foobar') if all input is available at once, - # but returs 1('foo') if parts of the final 'bar' arrive late - - After a match is found the instance attributes 'before', 'after' and - 'match' will be set. You can see all the data read before the match in - 'before'. You can see the data that was matched in 'after'. The - re.MatchObject used in the re match will be in 'match'. If an error - occurred then 'before' will be set to all the data read so far and - 'after' and 'match' will be None. - - If timeout is -1 then timeout will be set to the self.timeout value. - - A list entry may be EOF or TIMEOUT instead of a string. This will - catch these exceptions and return the index of the list entry instead - of raising the exception. The attribute 'after' will be set to the - exception type. The attribute 'match' will be None. This allows you to - write code like this:: - - index = p.expect(['good', 'bad', pexpect.EOF, pexpect.TIMEOUT]) - if index == 0: - do_something() - elif index == 1: - do_something_else() - elif index == 2: - do_some_other_thing() - elif index == 3: - do_something_completely_different() - - instead of code like this:: - - try: - index = p.expect(['good', 'bad']) - if index == 0: - do_something() - elif index == 1: - do_something_else() - except EOF: - do_some_other_thing() - except TIMEOUT: - do_something_completely_different() - - These two forms are equivalent. It all depends on what you want. You - can also just expect the EOF if you are waiting for all output of a - child to finish. For example:: - - p = pexpect.spawn('/bin/ls') - p.expect(pexpect.EOF) - print p.before - - If you are trying to optimize for speed then see expect_list(). - ''' - - compiled_pattern_list = self.compile_pattern_list(pattern) - return self.expect_list(compiled_pattern_list, - timeout, searchwindowsize) - - def expect_list(self, pattern_list, timeout=-1, searchwindowsize=-1): - - '''This takes a list of compiled regular expressions and returns the - index into the pattern_list that matched the child output. The list may - also contain EOF or TIMEOUT(which are not compiled regular - expressions). This method is similar to the expect() method except that - expect_list() does not recompile the pattern list on every call. This - may help if you are trying to optimize for speed, otherwise just use - the expect() method. This is called by expect(). If timeout==-1 then - the self.timeout value is used. If searchwindowsize==-1 then the - self.searchwindowsize value is used. ''' - - return self.expect_loop(searcher_re(pattern_list), - timeout, searchwindowsize) - - def expect_exact(self, pattern_list, timeout=-1, searchwindowsize=-1): - - '''This is similar to expect(), but uses plain string matching instead - of compiled regular expressions in 'pattern_list'. The 'pattern_list' - may be a string; a list or other sequence of strings; or TIMEOUT and - EOF. - - This call might be faster than expect() for two reasons: string - searching is faster than RE matching and it is possible to limit the - search to just the end of the input buffer. - - This method is also useful when you don't want to have to worry about - escaping regular expression characters that you want to match.''' - - if (type(pattern_list) in types.StringTypes or - pattern_list in (TIMEOUT, EOF)): - pattern_list = [pattern_list] - return self.expect_loop(searcher_string(pattern_list), - timeout, searchwindowsize) - - def expect_loop(self, searcher, timeout=-1, searchwindowsize=-1): - - '''This is the common loop used inside expect. The 'searcher' should be - an instance of searcher_re or searcher_string, which describes how and - what to search for in the input. - - See expect() for other arguments, return value and exceptions. ''' - - self.searcher = searcher - - if timeout == -1: - timeout = self.timeout - if timeout is not None: - end_time = time.time() + timeout - if searchwindowsize == -1: - searchwindowsize = self.searchwindowsize - - try: - incoming = self.buffer - freshlen = len(incoming) - while True: - # Keep reading until exception or return. - index = searcher.search(incoming, freshlen, searchwindowsize) - if index >= 0: - self.buffer = incoming[searcher.end:] - self.before = incoming[: searcher.start] - self.after = incoming[searcher.start: searcher.end] - self.match = searcher.match - self.match_index = index - return self.match_index - # No match at this point - if timeout < 0 and timeout is not None: - raise TIMEOUT('Timeout exceeded in expect_any().') - # Still have time left, so read more data - c = self.read_nonblocking(self.maxread, timeout) - freshlen = len(c) - time.sleep(0.0001) - incoming = incoming + c - if timeout is not None: - timeout = end_time - time.time() - except EOF, e: - self.buffer = '' - self.before = incoming - self.after = EOF - index = searcher.eof_index - if index >= 0: - self.match = EOF - self.match_index = index - return self.match_index - else: - self.match = None - self.match_index = None - raise EOF(str(e) + '\n' + str(self)) - except TIMEOUT, e: - self.buffer = incoming - self.before = incoming - self.after = TIMEOUT - index = searcher.timeout_index - if index >= 0: - self.match = TIMEOUT - self.match_index = index - return self.match_index - else: - self.match = None - self.match_index = None - raise TIMEOUT(str(e) + '\n' + str(self)) - except: - self.before = incoming - self.after = None - self.match = None - self.match_index = None - raise - - def getwinsize(self): - - '''This returns the terminal window size of the child tty. The return - value is a tuple of (rows, cols). ''' - - TIOCGWINSZ = getattr(termios, 'TIOCGWINSZ', 1074295912) - s = struct.pack('HHHH', 0, 0, 0, 0) - x = fcntl.ioctl(self.fileno(), TIOCGWINSZ, s) - return struct.unpack('HHHH', x)[0:2] - - def setwinsize(self, rows, cols): - - '''This sets the terminal window size of the child tty. This will cause - a SIGWINCH signal to be sent to the child. This does not change the - physical window size. It changes the size reported to TTY-aware - applications like vi or curses -- applications that respond to the - SIGWINCH signal. ''' - - # Check for buggy platforms. Some Python versions on some platforms - # (notably OSF1 Alpha and RedHat 7.1) truncate the value for - # termios.TIOCSWINSZ. It is not clear why this happens. - # These platforms don't seem to handle the signed int very well; - # yet other platforms like OpenBSD have a large negative value for - # TIOCSWINSZ and they don't have a truncate problem. - # Newer versions of Linux have totally different values for TIOCSWINSZ. - # Note that this fix is a hack. - TIOCSWINSZ = getattr(termios, 'TIOCSWINSZ', -2146929561) - if TIOCSWINSZ == 2148037735: - # Same bits, but with sign. - TIOCSWINSZ = -2146929561 - # Note, assume ws_xpixel and ws_ypixel are zero. - s = struct.pack('HHHH', rows, cols, 0, 0) - fcntl.ioctl(self.fileno(), TIOCSWINSZ, s) - - def interact(self, escape_character=chr(29), - input_filter=None, output_filter=None): - - '''This gives control of the child process to the interactive user (the - human at the keyboard). Keystrokes are sent to the child process, and - the stdout and stderr output of the child process is printed. This - simply echos the child stdout and child stderr to the real stdout and - it echos the real stdin to the child stdin. When the user types the - escape_character this method will stop. The default for - escape_character is ^]. This should not be confused with ASCII 27 -- - the ESC character. ASCII 29 was chosen for historical merit because - this is the character used by 'telnet' as the escape character. The - escape_character will not be sent to the child process. - - You may pass in optional input and output filter functions. These - functions should take a string and return a string. The output_filter - will be passed all the output from the child process. The input_filter - will be passed all the keyboard input from the user. The input_filter - is run BEFORE the check for the escape_character. - - Note that if you change the window size of the parent the SIGWINCH - signal will not be passed through to the child. If you want the child - window size to change when the parent's window size changes then do - something like the following example:: - - import pexpect, struct, fcntl, termios, signal, sys - def sigwinch_passthrough (sig, data): - s = struct.pack("HHHH", 0, 0, 0, 0) - a = struct.unpack('hhhh', fcntl.ioctl(sys.stdout.fileno(), - termios.TIOCGWINSZ , s)) - global p - p.setwinsize(a[0],a[1]) - # Note this 'p' global and used in sigwinch_passthrough. - p = pexpect.spawn('/bin/bash') - signal.signal(signal.SIGWINCH, sigwinch_passthrough) - p.interact() - ''' - - # Flush the buffer. - self.stdout.write(self.buffer) - self.stdout.flush() - self.buffer = '' - mode = tty.tcgetattr(self.STDIN_FILENO) - tty.setraw(self.STDIN_FILENO) - try: - self.__interact_copy(escape_character, input_filter, output_filter) - finally: - tty.tcsetattr(self.STDIN_FILENO, tty.TCSAFLUSH, mode) - - def __interact_writen(self, fd, data): - - '''This is used by the interact() method. - ''' - - while data != '' and self.isalive(): - n = os.write(fd, data) - data = data[n:] - - def __interact_read(self, fd): - - '''This is used by the interact() method. - ''' - - return os.read(fd, 1000) - - def __interact_copy(self, escape_character=None, - input_filter=None, output_filter=None): - - '''This is used by the interact() method. - ''' - - while self.isalive(): - r, w, e = self.__select([self.child_fd, self.STDIN_FILENO], [], []) - if self.child_fd in r: - data = self.__interact_read(self.child_fd) - if output_filter: - data = output_filter(data) - if self.logfile is not None: - self.logfile.write(data) - self.logfile.flush() - os.write(self.STDOUT_FILENO, data) - if self.STDIN_FILENO in r: - data = self.__interact_read(self.STDIN_FILENO) - if input_filter: - data = input_filter(data) - i = data.rfind(escape_character) - if i != -1: - data = data[:i] - self.__interact_writen(self.child_fd, data) - break - self.__interact_writen(self.child_fd, data) - - def __select(self, iwtd, owtd, ewtd, timeout=None): - - '''This is a wrapper around select.select() that ignores signals. If - select.select raises a select.error exception and errno is an EINTR - error then it is ignored. Mainly this is used to ignore sigwinch - (terminal resize). ''' - - # if select() is interrupted by a signal (errno==EINTR) then - # we loop back and enter the select() again. - if timeout is not None: - end_time = time.time() + timeout - while True: - try: - return select.select(iwtd, owtd, ewtd, timeout) - except select.error, e: - if e[0] == errno.EINTR: - # if we loop back we have to subtract the - # amount of time we already waited. - if timeout is not None: - timeout = end_time - time.time() - if timeout < 0: - return([], [], []) - else: - # something else caused the select.error, so - # this actually is an exception. - raise - -############################################################################## -# The following methods are no longer supported or allowed. - - def setmaxread(self, maxread): - - '''This method is no longer supported or allowed. I don't like getters - and setters without a good reason. ''' - - raise ExceptionPexpect('This method is no longer supported ' + - 'or allowed. Just assign a value to the ' + - 'maxread member variable.') - - def setlog(self, fileobject): - - '''This method is no longer supported or allowed. - ''' - - raise ExceptionPexpect('This method is no longer supported ' + - 'or allowed. Just assign a value to the logfile ' + - 'member variable.') - -############################################################################## -# End of spawn class -############################################################################## - - -class searcher_string(object): - - '''This is a plain string search helper for the spawn.expect_any() method. - This helper class is for speed. For more powerful regex patterns - see the helper class, searcher_re. - - Attributes: - - eof_index - index of EOF, or -1 - timeout_index - index of TIMEOUT, or -1 - - After a successful match by the search() method the following attributes - are available: - - start - index into the buffer, first byte of match - end - index into the buffer, first byte after match - match - the matching string itself - - ''' - - def __init__(self, strings): - - '''This creates an instance of searcher_string. This argument 'strings' - may be a list; a sequence of strings; or the EOF or TIMEOUT types. ''' - - self.eof_index = -1 - self.timeout_index = -1 - self._strings = [] - for n, s in zip(list(range(len(strings))), strings): - if s is EOF: - self.eof_index = n - continue - if s is TIMEOUT: - self.timeout_index = n - continue - self._strings.append((n, s)) - - def __str__(self): - - '''This returns a human-readable string that represents the state of - the object.''' - - ss = [(ns[0], ' %d: "%s"' % ns) for ns in self._strings] - ss.append((-1, 'searcher_string:')) - if self.eof_index >= 0: - ss.append((self.eof_index, ' %d: EOF' % self.eof_index)) - if self.timeout_index >= 0: - ss.append((self.timeout_index, - ' %d: TIMEOUT' % self.timeout_index)) - ss.sort() - ss = zip(*ss)[1] - return '\n'.join(ss) - - def search(self, buffer, freshlen, searchwindowsize=None): - - '''This searches 'buffer' for the first occurence of one of the search - strings. 'freshlen' must indicate the number of bytes at the end of - 'buffer' which have not been searched before. It helps to avoid - searching the same, possibly big, buffer over and over again. - - See class spawn for the 'searchwindowsize' argument. - - If there is a match this returns the index of that string, and sets - 'start', 'end' and 'match'. Otherwise, this returns -1. ''' - - absurd_match = len(buffer) - first_match = absurd_match - - # 'freshlen' helps a lot here. Further optimizations could - # possibly include: - # - # using something like the Boyer-Moore Fast String Searching - # Algorithm; pre-compiling the search through a list of - # strings into something that can scan the input once to - # search for all N strings; realize that if we search for - # ['bar', 'baz'] and the input is '...foo' we need not bother - # rescanning until we've read three more bytes. - # - # Sadly, I don't know enough about this interesting topic. /grahn - - for index, s in self._strings: - if searchwindowsize is None: - # the match, if any, can only be in the fresh data, - # or at the very end of the old data - offset = -(freshlen + len(s)) - else: - # better obey searchwindowsize - offset = -searchwindowsize - n = buffer.find(s, offset) - if n >= 0 and n < first_match: - first_match = n - best_index, best_match = index, s - if first_match == absurd_match: - return -1 - self.match = best_match - self.start = first_match - self.end = self.start + len(self.match) - return best_index - - -class searcher_re(object): - - '''This is regular expression string search helper for the - spawn.expect_any() method. This helper class is for powerful - pattern matching. For speed, see the helper class, searcher_string. - - Attributes: - - eof_index - index of EOF, or -1 - timeout_index - index of TIMEOUT, or -1 - - After a successful match by the search() method the following attributes - are available: - - start - index into the buffer, first byte of match - end - index into the buffer, first byte after match - match - the re.match object returned by a succesful re.search - - ''' - - def __init__(self, patterns): - - '''This creates an instance that searches for 'patterns' Where - 'patterns' may be a list or other sequence of compiled regular - expressions, or the EOF or TIMEOUT types.''' - - self.eof_index = -1 - self.timeout_index = -1 - self._searches = [] - for n, s in zip(list(range(len(patterns))), patterns): - if s is EOF: - self.eof_index = n - continue - if s is TIMEOUT: - self.timeout_index = n - continue - self._searches.append((n, s)) - - def __str__(self): - - '''This returns a human-readable string that represents the state of - the object.''' - - ss = [(n, ' %d: re.compile("%s")' % - (n, str(s.pattern))) for n, s in self._searches] - ss.append((-1, 'searcher_re:')) - if self.eof_index >= 0: - ss.append((self.eof_index, ' %d: EOF' % self.eof_index)) - if self.timeout_index >= 0: - ss.append((self.timeout_index, ' %d: TIMEOUT' % - self.timeout_index)) - ss.sort() - ss = zip(*ss)[1] - return '\n'.join(ss) - - def search(self, buffer, freshlen, searchwindowsize=None): - - '''This searches 'buffer' for the first occurence of one of the regular - expressions. 'freshlen' must indicate the number of bytes at the end of - 'buffer' which have not been searched before. - - See class spawn for the 'searchwindowsize' argument. - - If there is a match this returns the index of that string, and sets - 'start', 'end' and 'match'. Otherwise, returns -1.''' - - absurd_match = len(buffer) - first_match = absurd_match - # 'freshlen' doesn't help here -- we cannot predict the - # length of a match, and the re module provides no help. - if searchwindowsize is None: - searchstart = 0 - else: - searchstart = max(0, len(buffer) - searchwindowsize) - for index, s in self._searches: - match = s.search(buffer, searchstart) - if match is None: - continue - n = match.start() - if n < first_match: - first_match = n - the_match = match - best_index = index - if first_match == absurd_match: - return -1 - self.start = first_match - self.match = the_match - self.end = self.match.end() - return best_index - - -def which(filename): - - '''This takes a given filename; tries to find it in the environment path; - then checks if it is executable. This returns the full path to the filename - if found and executable. Otherwise this returns None.''' - - # Special case where filename contains an explicit path. - if os.path.dirname(filename) != '': - if os.access(filename, os.X_OK): - return filename - if 'PATH' not in os.environ or os.environ['PATH'] == '': - p = os.defpath - else: - p = os.environ['PATH'] - pathlist = string.split(p, os.pathsep) - for path in pathlist: - ff = os.path.join(path, filename) - if os.access(ff, os.X_OK): - return ff - return None - - -def split_command_line(command_line): - - '''This splits a command line into a list of arguments. It splits arguments - on spaces, but handles embedded quotes, doublequotes, and escaped - characters. It's impossible to do this with a regular expression, so I - wrote a little state machine to parse the command line. ''' - - arg_list = [] - arg = '' - - # Constants to name the states we can be in. - state_basic = 0 - state_esc = 1 - state_singlequote = 2 - state_doublequote = 3 - # The state when consuming whitespace between commands. - state_whitespace = 4 - state = state_basic - - for c in command_line: - if state == state_basic or state == state_whitespace: - if c == '\\': - # Escape the next character - state = state_esc - elif c == r"'": - # Handle single quote - state = state_singlequote - elif c == r'"': - # Handle double quote - state = state_doublequote - elif c.isspace(): - # Add arg to arg_list if we aren't in the middle of whitespace. - if state == state_whitespace: - # Do nothing. - None - else: - arg_list.append(arg) - arg = '' - state = state_whitespace - else: - arg = arg + c - state = state_basic - elif state == state_esc: - arg = arg + c - state = state_basic - elif state == state_singlequote: - if c == r"'": - state = state_basic - else: - arg = arg + c - elif state == state_doublequote: - if c == r'"': - state = state_basic - else: - arg = arg + c - - if arg != '': - arg_list.append(arg) - return arg_list - -# vi:set sr et ts=4 sw=4 ft=python : diff --git a/pexpect/psh.py b/pexpect/psh.py deleted file mode 100644 index 467f546..0000000 --- a/pexpect/psh.py +++ /dev/null @@ -1,185 +0,0 @@ -'''This is a utility class to make shell scripting easier in Python. -It combines Pexpect and wraps many Standard Python Library functions -to make them look more shell-like. - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import pexpect, os, sys, re -from types import * - -class ExceptionPsh(pexpect.ExceptionPexpect): - - '''Raised for Psh exceptions. - ''' - -class ExceptionErrorCode(ExceptionPsh): - - '''Raised when an program returns an error code. - ''' - - def __init__(self, string, err_code, cmd_output): - - ExceptionPsh.__init__(self,string) - self.error = err_code - self.output = cmd_output - -class psh (object): - - def __init__ (self,exp): - - self.exp = exp - self.default_timeout = 30 # Seconds - - def ls (self, path=''): - - fileStr = self.run("ls %s" % path) - return fileStr.split() - - def cd (self, path='-'): - - return self.run("cd %s" % path) - - def rm (self, path=''): - - return self.run("/bin/rm -f %s" % path) - - def cp (self, path_from='', path_to=''): - - return self.run("/bin/cp %s %s" % (path_from, path_to)) - - def mv (self, path_from='', path_to=''): - - return self.run("/bin/mv %s %s" % (path_from, path_to)) - - def pwd (self): - - return self.run("/bin/pwd") - - def which (self, exe_name): - - return self.run("/usr/bin/which %s" % exe_name) - - def chown (self, path, user='', group=None, recurse=False): - - xtra_flags = "" - if recurse: xtra_flags = "-R" - if group: group = ':' + group - else: group = "" - - return self.run("/bin/chmod %s %s%s %s" % (recurse,user,group,path)) - - def chmod (self, path, perms='', recurse=False): - - xtra_flags = "" - if recurse: xtra_flags = "-R" - return self.run("/usr/bin/chmod %s %s %s" % (xtra_flags, perms, path)) - - def chattr (self, path, attrs='', recurse=False): - - xtra_flags = "" - if recurse: xtra_flags = "-R" - return self.run("/usr/bin/chattr %s %s %s" % (xtra_flags, attrs, path)) - - def cat (self, path): - - return self.run("/bin/cat %s" % path) - - def run (self, cmd, stim_resp_dict = {}, timeout=None): - - (ret, output) = self.run_raw(cmd, stim_resp_dict, timeout) - if ret == 0: return output - raise ExceptionErrorCode("Running command [%s] returned error [%d]" - % (cmd,ret), ret, output) - - def run_raw(self, cmd, stim_resp_dict=None, timeout=None): - - '''Someone contributed this, but now I've lost touch and I forget the - motive of this. It was sort of a sketch at the time which doesn't make - this any easier to prioritize, but it seemed important at the time. ''' - - if not timeout: timeout = self.default_timeout - - def cmd_exp_loop(param): - if type(param) is DictType: - param = (param,) - for item in param: - if type(item) is type(()) or type(item) is type([]): - cmd_exp_loop(item) - elif type(item) is type(""): - self.exp.send(item) - elif type(item) is type({}): - dict = item - while(1): - stimulus = dict.keys() - idx = self.exp.expect_exact(stimulus, timeout) - keys = dict.keys() - respond = dict[keys[idx]] - if ( type(respond) is type({}) - or type(respond) is type(()) - or type(item) is type([]) ): - cmd_exp_loop(respond) - if type(respond) is type(""): - self.exp.send(respond) - elif ( type(respond) is InstanceType - and Exception - in inspect.getmro(respond.__class__) ): - raise respond - elif type(respond) is type(0): - return (respond, self.exp.before) - elif respond is None: - break - else: - self.exp.send(str(respond)) - - if stim_resp_dict == None: - stim_resp_dict = {} - - self.exp.sendline("") - if not self.exp.prompt(): raise SessionException("No prompt") - self.exp.sendline(cmd) - self.exp.expect_exact([cmd]) - stim_resp_dict[re.compile(self.exp.PROMPT)] = None - cmd_exp_loop(stim_resp_dict) - - output = self.exp.before - # Get the return code - self.exp.sendline("echo $?") - self.exp.expect_exact(["echo $?"]) - if not self.exp.prompt(): - raise SessionException("No prompt", 0, self.exp.before) - try: - reg = re.compile("^(\d+)") - s = self.exp.before.strip() - #print s - #pdb.set_trace() - s = reg.search(s).groups()[0] - error_code = int(s) - except ValueError: - log.error("Cannot parse %s into an int!" % self.exp.before) - raise - - if not output[0:2] == '\r\n': - log.warning("Returned output lacks leading \\r\\n which may indicate a tae error") - log.debug2("Offending output string: [%s]" % output) - return (error_code, output) - else: - return(error_code, output[2:]) - -# def pipe (self, cmd, string_to_send): diff --git a/pexpect/pxssh.py b/pexpect/pxssh.py deleted file mode 100644 index 5566029..0000000 --- a/pexpect/pxssh.py +++ /dev/null @@ -1,347 +0,0 @@ -'''This class extends pexpect.spawn to specialize setting up SSH connections. -This adds methods for login, logout, and expecting the shell prompt. - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -from pexpect import * -import pexpect -import time -import os - -__all__ = ['ExceptionPxssh', 'pxssh'] - -# Exception classes used by this module. -class ExceptionPxssh(ExceptionPexpect): - '''Raised for pxssh exceptions. - ''' - -class pxssh (spawn): - - '''This class extends pexpect.spawn to specialize setting up SSH - connections. This adds methods for login, logout, and expecting the shell - prompt. It does various tricky things to handle many situations in the SSH - login process. For example, if the session is your first login, then pxssh - automatically accepts the remote certificate; or if you have public key - authentication setup then pxssh won't wait for the password prompt. - - pxssh uses the shell prompt to synchronize output from the remote host. In - order to make this more robust it sets the shell prompt to something more - unique than just $ or #. This should work on most Borne/Bash or Csh style - shells. - - Example that runs a few commands on a remote server and prints the result:: - - import pxssh - import getpass - try: - s = pxssh.pxssh() - hostname = raw_input('hostname: ') - username = raw_input('username: ') - password = getpass.getpass('password: ') - s.login (hostname, username, password) - s.sendline ('uptime') # run a command - s.prompt() # match the prompt - print s.before # print everything before the prompt. - s.sendline ('ls -l') - s.prompt() - print s.before - s.sendline ('df') - s.prompt() - print s.before - s.logout() - except pxssh.ExceptionPxssh, e: - print "pxssh failed on login." - print str(e) - - Note that if you have ssh-agent running while doing development with pxssh - then this can lead to a lot of confusion. Many X display managers (xdm, - gdm, kdm, etc.) will automatically start a GUI agent. You may see a GUI - dialog box popup asking for a password during development. You should turn - off any key agents during testing. The 'force_password' attribute will turn - off public key authentication. This will only work if the remote SSH server - is configured to allow password logins. Example of using 'force_password' - attribute:: - - s = pxssh.pxssh() - s.force_password = True - hostname = raw_input('hostname: ') - username = raw_input('username: ') - password = getpass.getpass('password: ') - s.login (hostname, username, password) - ''' - - def __init__ (self, timeout=30, maxread=2000, searchwindowsize=None, logfile=None, cwd=None, env=None): - - spawn.__init__(self, None, timeout=timeout, maxread=maxread, searchwindowsize=searchwindowsize, logfile=logfile, cwd=cwd, env=env) - - self.name = '<pxssh>' - - #SUBTLE HACK ALERT! Note that the command that SETS the prompt uses a - #slightly different string than the regular expression to match it. This - #is because when you set the prompt the command will echo back, but we - #don't want to match the echoed command. So if we make the set command - #slightly different than the regex we eliminate the problem. To make the - #set command different we add a backslash in front of $. The $ doesn't - #need to be escaped, but it doesn't hurt and serves to make the set - #prompt command different than the regex. - - # used to match the command-line prompt - self.UNIQUE_PROMPT = "\[PEXPECT\][\$\#] " - self.PROMPT = self.UNIQUE_PROMPT - - # used to set shell command-line prompt to UNIQUE_PROMPT. - self.PROMPT_SET_SH = "PS1='[PEXPECT]\$ '" - self.PROMPT_SET_CSH = "set prompt='[PEXPECT]\$ '" - self.SSH_OPTS = ("-o'RSAAuthentication=no'" - + " -o 'PubkeyAuthentication=no'") -# Disabling host key checking, makes you vulnerable to MITM attacks. -# + " -o 'StrictHostKeyChecking=no'" -# + " -o 'UserKnownHostsFile /dev/null' ") - # Disabling X11 forwarding gets rid of the annoying SSH_ASKPASS from - # displaying a GUI password dialog. I have not figured out how to - # disable only SSH_ASKPASS without also disabling X11 forwarding. - # Unsetting SSH_ASKPASS on the remote side doesn't disable it! Annoying! - #self.SSH_OPTS = "-x -o'RSAAuthentication=no' -o 'PubkeyAuthentication=no'" - self.force_password = False - self.auto_prompt_reset = True - - def levenshtein_distance(self, a,b): - - '''This calculates the Levenshtein distance between a and b. - ''' - - n, m = len(a), len(b) - if n > m: - a,b = b,a - n,m = m,n - current = range(n+1) - for i in range(1,m+1): - previous, current = current, [i]+[0]*n - for j in range(1,n+1): - add, delete = previous[j]+1, current[j-1]+1 - change = previous[j-1] - if a[j-1] != b[i-1]: - change = change + 1 - current[j] = min(add, delete, change) - return current[n] - - def sync_original_prompt (self): - - '''This attempts to find the prompt. Basically, press enter and record - the response; press enter again and record the response; if the two - responses are similar then assume we are at the original prompt. This - is a slow function. It can take over 10 seconds. ''' - - # All of these timing pace values are magic. - # I came up with these based on what seemed reliable for - # connecting to a heavily loaded machine I have. - self.sendline() - time.sleep(0.1) - # If latency is worse than these values then this will fail. - - try: - # Clear the buffer before getting the prompt. - self.read_nonblocking(size=10000,timeout=1) - except TIMEOUT: - pass - time.sleep(0.1) - self.sendline() - time.sleep(0.5) - x = self.read_nonblocking(size=1000,timeout=1) - time.sleep(0.1) - self.sendline() - time.sleep(0.5) - a = self.read_nonblocking(size=1000,timeout=1) - time.sleep(0.1) - self.sendline() - time.sleep(0.5) - b = self.read_nonblocking(size=1000,timeout=1) - ld = self.levenshtein_distance(a,b) - len_a = len(a) - if len_a == 0: - return False - if float(ld)/len_a < 0.4: - return True - return False - - ### TODO: This is getting messy and I'm pretty sure this isn't perfect. - ### TODO: I need to draw a flow chart for this. - def login (self,server,username,password='',terminal_type='ansi',original_prompt=r"[#$]",login_timeout=10,port=None,auto_prompt_reset=True,ssh_key=None): - - '''This logs the user into the given server. It uses the - 'original_prompt' to try to find the prompt right after login. When it - finds the prompt it immediately tries to reset the prompt to something - more easily matched. The default 'original_prompt' is very optimistic - and is easily fooled. It's more reliable to try to match the original - prompt as exactly as possible to prevent false matches by server - strings such as the "Message Of The Day". On many systems you can - disable the MOTD on the remote server by creating a zero-length file - called "~/.hushlogin" on the remote server. If a prompt cannot be found - then this will not necessarily cause the login to fail. In the case of - a timeout when looking for the prompt we assume that the original - prompt was so weird that we could not match it, so we use a few tricks - to guess when we have reached the prompt. Then we hope for the best and - blindly try to reset the prompt to something more unique. If that fails - then login() raises an ExceptionPxssh exception. - - In some situations it is not possible or desirable to reset the - original prompt. In this case, set 'auto_prompt_reset' to False to - inhibit setting the prompt to the UNIQUE_PROMPT. Remember that pxssh - uses a unique prompt in the prompt() method. If the original prompt is - not reset then this will disable the prompt() method unless you - manually set the PROMPT attribute. ''' - - ssh_options = '-q' - if self.force_password: - ssh_options = ssh_options + ' ' + self.SSH_OPTS - if port is not None: - ssh_options = ssh_options + ' -p %s'%(str(port)) - if ssh_key is not None: - try: - os.path.isfile(ssh_key) - except: - raise ExceptionPxssh ('private ssh key does not exist') - ssh_options = ssh_options + ' -i %s' % (ssh_key) - cmd = "ssh %s -l %s %s" % (ssh_options, username, server) - - # This does not distinguish between a remote server 'password' prompt - # and a local ssh 'passphrase' prompt (for unlocking a private key). - spawn._spawn(self, cmd) - i = self.expect(["(?i)are you sure you want to continue connecting", original_prompt, "(?i)(?:password)|(?:passphrase for key)", "(?i)permission denied", "(?i)terminal type", TIMEOUT, "(?i)connection closed by remote host"], timeout=login_timeout) - - # First phase - if i==0: - # New certificate -- always accept it. - # This is what you get if SSH does not have the remote host's - # public key stored in the 'known_hosts' cache. - self.sendline("yes") - i = self.expect(["(?i)are you sure you want to continue connecting", original_prompt, "(?i)(?:password)|(?:passphrase for key)", "(?i)permission denied", "(?i)terminal type", TIMEOUT]) - if i==2: # password or passphrase - self.sendline(password) - i = self.expect(["(?i)are you sure you want to continue connecting", original_prompt, "(?i)(?:password)|(?:passphrase for key)", "(?i)permission denied", "(?i)terminal type", TIMEOUT]) - if i==4: - self.sendline(terminal_type) - i = self.expect(["(?i)are you sure you want to continue connecting", original_prompt, "(?i)(?:password)|(?:passphrase for key)", "(?i)permission denied", "(?i)terminal type", TIMEOUT]) - - # Second phase - if i==0: - # This is weird. This should not happen twice in a row. - self.close() - raise ExceptionPxssh ('Weird error. Got "are you sure" prompt twice.') - elif i==1: # can occur if you have a public key pair set to authenticate. - ### TODO: May NOT be OK if expect() got tricked and matched a false prompt. - pass - elif i==2: # password prompt again - # For incorrect passwords, some ssh servers will - # ask for the password again, others return 'denied' right away. - # If we get the password prompt again then this means - # we didn't get the password right the first time. - self.close() - raise ExceptionPxssh ('password refused') - elif i==3: # permission denied -- password was bad. - self.close() - raise ExceptionPxssh ('permission denied') - elif i==4: # terminal type again? WTF? - self.close() - raise ExceptionPxssh ('Weird error. Got "terminal type" prompt twice.') - elif i==5: # Timeout - #This is tricky... I presume that we are at the command-line prompt. - #It may be that the shell prompt was so weird that we couldn't match - #it. Or it may be that we couldn't log in for some other reason. I - #can't be sure, but it's safe to guess that we did login because if - #I presume wrong and we are not logged in then this should be caught - #later when I try to set the shell prompt. - pass - elif i==6: # Connection closed by remote host - self.close() - raise ExceptionPxssh ('connection closed') - else: # Unexpected - self.close() - raise ExceptionPxssh ('unexpected login response') - if not self.sync_original_prompt(): - self.close() - raise ExceptionPxssh ('could not synchronize with original prompt') - # We appear to be in. - # set shell prompt to something unique. - if auto_prompt_reset: - if not self.set_unique_prompt(): - self.close() - raise ExceptionPxssh ('could not set shell prompt\n'+self.before) - return True - - def logout (self): - - '''This sends exit to the remote shell. If there are stopped jobs then - this automatically sends exit twice. ''' - - self.sendline("exit") - index = self.expect([EOF, "(?i)there are stopped jobs"]) - if index==1: - self.sendline("exit") - self.expect(EOF) - self.close() - - def prompt (self, timeout=-1): - - '''This matches the shell prompt. This is little more than a short-cut - to the expect() method. This returns True if the shell prompt was - matched. This returns False if a timeout was raised. Note that if you - called login() with auto_prompt_reset set to False then before calling - prompt() you must set the PROMPT attribute to a regex that prompt() - will use for matching the prompt. Calling prompt() will erase the - contents of the 'before' attribute even if no prompt is ever matched. - If timeout is not given or it is set to -1 then self.timeout is used. - ''' - - if timeout == -1: - timeout = self.timeout - i = self.expect([self.PROMPT, TIMEOUT], timeout=timeout) - if i==1: - return False - return True - - def set_unique_prompt (self): - - '''This sets the remote prompt to something more unique than # or $. - This makes it easier for the prompt() method to match the shell prompt - unambiguously. This method is called automatically by the login() - method, but you may want to call it manually if you somehow reset the - shell prompt. For example, if you 'su' to a different user then you - will need to manually reset the prompt. This sends shell commands to - the remote host to set the prompt, so this assumes the remote host is - ready to receive commands. - - Alternatively, you may use your own prompt pattern. Just set the PROMPT - attribute to a regular expression that matches it. In this case you - should call login() with auto_prompt_reset=False; then set the PROMPT - attribute. After that the prompt() method will try to match your prompt - pattern.''' - - self.sendline ("unset PROMPT_COMMAND") - self.sendline (self.PROMPT_SET_SH) # sh-style - i = self.expect ([TIMEOUT, self.PROMPT], timeout=10) - if i == 0: # csh-style - self.sendline (self.PROMPT_SET_CSH) - i = self.expect ([TIMEOUT, self.PROMPT], timeout=10) - if i == 0: - return False - return True - -# vi:ts=4:sw=4:expandtab:ft=python: diff --git a/pexpect/screen.py b/pexpect/screen.py deleted file mode 100644 index 655ab6f..0000000 --- a/pexpect/screen.py +++ /dev/null @@ -1,396 +0,0 @@ -'''This implements a virtual screen. This is used to support ANSI terminal -emulation. The screen representation and state is implemented in this class. -Most of the methods are inspired by ANSI screen control codes. The ANSI class -extends this class to add parsing of ANSI escape codes. - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import copy - -NUL = 0 # Fill character; ignored on input. -ENQ = 5 # Transmit answerback message. -BEL = 7 # Ring the bell. -BS = 8 # Move cursor left. -HT = 9 # Move cursor to next tab stop. -LF = 10 # Line feed. -VT = 11 # Same as LF. -FF = 12 # Same as LF. -CR = 13 # Move cursor to left margin or newline. -SO = 14 # Invoke G1 character set. -SI = 15 # Invoke G0 character set. -XON = 17 # Resume transmission. -XOFF = 19 # Halt transmission. -CAN = 24 # Cancel escape sequence. -SUB = 26 # Same as CAN. -ESC = 27 # Introduce a control sequence. -DEL = 127 # Fill character; ignored on input. -SPACE = chr(32) # Space or blank character. - -def constrain (n, min, max): - - '''This returns a number, n constrained to the min and max bounds. ''' - - if n < min: - return min - if n > max: - return max - return n - -class screen: - - '''This object maintains the state of a virtual text screen as a - rectangluar array. This maintains a virtual cursor position and handles - scrolling as characters are added. This supports most of the methods needed - by an ANSI text screen. Row and column indexes are 1-based (not zero-based, - like arrays). ''' - - def __init__ (self, r=24,c=80): - - '''This initializes a blank scree of the given dimentions.''' - - self.rows = r - self.cols = c - self.cur_r = 1 - self.cur_c = 1 - self.cur_saved_r = 1 - self.cur_saved_c = 1 - self.scroll_row_start = 1 - self.scroll_row_end = self.rows - self.w = [ [SPACE] * self.cols for c in range(self.rows)] - - def __str__ (self): - - '''This returns a printable representation of the screen. The end of - each screen line is terminated by a newline. ''' - - return '\n'.join ([ ''.join(c) for c in self.w ]) - - def dump (self): - - '''This returns a copy of the screen as a string. This is similar to - __str__ except that lines are not terminated with line feeds. ''' - - return ''.join ([ ''.join(c) for c in self.w ]) - - def pretty (self): - - '''This returns a copy of the screen as a string with an ASCII text box - around the screen border. This is similar to __str__ except that it - adds a box. ''' - - top_bot = '+' + '-'*self.cols + '+\n' - return top_bot + '\n'.join(['|'+line+'|' for line in str(self).split('\n')]) + '\n' + top_bot - - def fill (self, ch=SPACE): - - self.fill_region (1,1,self.rows,self.cols, ch) - - def fill_region (self, rs,cs, re,ce, ch=SPACE): - - rs = constrain (rs, 1, self.rows) - re = constrain (re, 1, self.rows) - cs = constrain (cs, 1, self.cols) - ce = constrain (ce, 1, self.cols) - if rs > re: - rs, re = re, rs - if cs > ce: - cs, ce = ce, cs - for r in range (rs, re+1): - for c in range (cs, ce + 1): - self.put_abs (r,c,ch) - - def cr (self): - - '''This moves the cursor to the beginning (col 1) of the current row. - ''' - - self.cursor_home (self.cur_r, 1) - - def lf (self): - - '''This moves the cursor down with scrolling. - ''' - - old_r = self.cur_r - self.cursor_down() - if old_r == self.cur_r: - self.scroll_up () - self.erase_line() - - def crlf (self): - - '''This advances the cursor with CRLF properties. - The cursor will line wrap and the screen may scroll. - ''' - - self.cr () - self.lf () - - def newline (self): - - '''This is an alias for crlf(). - ''' - - self.crlf() - - def put_abs (self, r, c, ch): - - '''Screen array starts at 1 index.''' - - r = constrain (r, 1, self.rows) - c = constrain (c, 1, self.cols) - ch = str(ch)[0] - self.w[r-1][c-1] = ch - - def put (self, ch): - - '''This puts a characters at the current cursor position. - ''' - - self.put_abs (self.cur_r, self.cur_c, ch) - - def insert_abs (self, r, c, ch): - - '''This inserts a character at (r,c). Everything under - and to the right is shifted right one character. - The last character of the line is lost. - ''' - - r = constrain (r, 1, self.rows) - c = constrain (c, 1, self.cols) - for ci in range (self.cols, c, -1): - self.put_abs (r,ci, self.get_abs(r,ci-1)) - self.put_abs (r,c,ch) - - def insert (self, ch): - - self.insert_abs (self.cur_r, self.cur_c, ch) - - def get_abs (self, r, c): - - r = constrain (r, 1, self.rows) - c = constrain (c, 1, self.cols) - return self.w[r-1][c-1] - - def get (self): - - self.get_abs (self.cur_r, self.cur_c) - - def get_region (self, rs,cs, re,ce): - - '''This returns a list of lines representing the region. - ''' - - rs = constrain (rs, 1, self.rows) - re = constrain (re, 1, self.rows) - cs = constrain (cs, 1, self.cols) - ce = constrain (ce, 1, self.cols) - if rs > re: - rs, re = re, rs - if cs > ce: - cs, ce = ce, cs - sc = [] - for r in range (rs, re+1): - line = '' - for c in range (cs, ce + 1): - ch = self.get_abs (r,c) - line = line + ch - sc.append (line) - return sc - - def cursor_constrain (self): - - '''This keeps the cursor within the screen area. - ''' - - self.cur_r = constrain (self.cur_r, 1, self.rows) - self.cur_c = constrain (self.cur_c, 1, self.cols) - - def cursor_home (self, r=1, c=1): # <ESC>[{ROW};{COLUMN}H - - self.cur_r = r - self.cur_c = c - self.cursor_constrain () - - def cursor_back (self,count=1): # <ESC>[{COUNT}D (not confused with down) - - self.cur_c = self.cur_c - count - self.cursor_constrain () - - def cursor_down (self,count=1): # <ESC>[{COUNT}B (not confused with back) - - self.cur_r = self.cur_r + count - self.cursor_constrain () - - def cursor_forward (self,count=1): # <ESC>[{COUNT}C - - self.cur_c = self.cur_c + count - self.cursor_constrain () - - def cursor_up (self,count=1): # <ESC>[{COUNT}A - - self.cur_r = self.cur_r - count - self.cursor_constrain () - - def cursor_up_reverse (self): # <ESC> M (called RI -- Reverse Index) - - old_r = self.cur_r - self.cursor_up() - if old_r == self.cur_r: - self.scroll_up() - - def cursor_force_position (self, r, c): # <ESC>[{ROW};{COLUMN}f - - '''Identical to Cursor Home.''' - - self.cursor_home (r, c) - - def cursor_save (self): # <ESC>[s - - '''Save current cursor position.''' - - self.cursor_save_attrs() - - def cursor_unsave (self): # <ESC>[u - - '''Restores cursor position after a Save Cursor.''' - - self.cursor_restore_attrs() - - def cursor_save_attrs (self): # <ESC>7 - - '''Save current cursor position.''' - - self.cur_saved_r = self.cur_r - self.cur_saved_c = self.cur_c - - def cursor_restore_attrs (self): # <ESC>8 - - '''Restores cursor position after a Save Cursor.''' - - self.cursor_home (self.cur_saved_r, self.cur_saved_c) - - def scroll_constrain (self): - - '''This keeps the scroll region within the screen region.''' - - if self.scroll_row_start <= 0: - self.scroll_row_start = 1 - if self.scroll_row_end > self.rows: - self.scroll_row_end = self.rows - - def scroll_screen (self): # <ESC>[r - - '''Enable scrolling for entire display.''' - - self.scroll_row_start = 1 - self.scroll_row_end = self.rows - - def scroll_screen_rows (self, rs, re): # <ESC>[{start};{end}r - - '''Enable scrolling from row {start} to row {end}.''' - - self.scroll_row_start = rs - self.scroll_row_end = re - self.scroll_constrain() - - def scroll_down (self): # <ESC>D - - '''Scroll display down one line.''' - - # Screen is indexed from 1, but arrays are indexed from 0. - s = self.scroll_row_start - 1 - e = self.scroll_row_end - 1 - self.w[s+1:e+1] = copy.deepcopy(self.w[s:e]) - - def scroll_up (self): # <ESC>M - - '''Scroll display up one line.''' - - # Screen is indexed from 1, but arrays are indexed from 0. - s = self.scroll_row_start - 1 - e = self.scroll_row_end - 1 - self.w[s:e] = copy.deepcopy(self.w[s+1:e+1]) - - def erase_end_of_line (self): # <ESC>[0K -or- <ESC>[K - - '''Erases from the current cursor position to the end of the current - line.''' - - self.fill_region (self.cur_r, self.cur_c, self.cur_r, self.cols) - - def erase_start_of_line (self): # <ESC>[1K - - '''Erases from the current cursor position to the start of the current - line.''' - - self.fill_region (self.cur_r, 1, self.cur_r, self.cur_c) - - def erase_line (self): # <ESC>[2K - - '''Erases the entire current line.''' - - self.fill_region (self.cur_r, 1, self.cur_r, self.cols) - - def erase_down (self): # <ESC>[0J -or- <ESC>[J - - '''Erases the screen from the current line down to the bottom of the - screen.''' - - self.erase_end_of_line () - self.fill_region (self.cur_r + 1, 1, self.rows, self.cols) - - def erase_up (self): # <ESC>[1J - - '''Erases the screen from the current line up to the top of the - screen.''' - - self.erase_start_of_line () - self.fill_region (self.cur_r-1, 1, 1, self.cols) - - def erase_screen (self): # <ESC>[2J - - '''Erases the screen with the background color.''' - - self.fill () - - def set_tab (self): # <ESC>H - - '''Sets a tab at the current position.''' - - pass - - def clear_tab (self): # <ESC>[g - - '''Clears tab at the current position.''' - - pass - - def clear_all_tabs (self): # <ESC>[3g - - '''Clears all tabs.''' - - pass - -# Insert line Esc [ Pn L -# Delete line Esc [ Pn M -# Delete character Esc [ Pn P -# Scrolling region Esc [ Pn(top);Pn(bot) r - diff --git a/pexpect/setup.py.template b/pexpect/setup.py.template deleted file mode 100644 index d63bc98..0000000 --- a/pexpect/setup.py.template +++ /dev/null @@ -1,39 +0,0 @@ -''' -$Revision: 485 $ -$Date: 2007-07-12 15:23:15 -0700 (Thu, 12 Jul 2007) $ -''' -from distutils.core import setup -setup (name='pexpect', - version='VERSION', - py_modules=['pexpect', 'pxssh', 'fdpexpect', 'FSM', 'screen', 'ANSI'], - description='Pexpect is a pure Python Expect. It allows easy control of other applications.', - author='Noah Spurrier', - author_email='noah@noah.org', - url='http://pexpect.sourceforge.net/', - license='MIT license', - platforms='UNIX', -) - -# classifiers = [ -# 'Development Status :: 4 - Beta', -# 'Environment :: Console', -# 'Environment :: Console (Text Based)', -# 'Intended Audience :: Developers', -# 'Intended Audience :: System Administrators', -# 'Intended Audience :: Quality Engineers', -# 'License :: OSI Approved :: Python Software Foundation License', -# 'Operating System :: POSIX', -# 'Operating System :: MacOS :: MacOS X', -# 'Programming Language :: Python', -# 'Topic :: Software Development', -# 'Topic :: Software Development :: Libraries :: Python Modules', -# 'Topic :: Software Development :: Quality Assurance', -# 'Topic :: Software Development :: Testing', -# 'Topic :: System, System :: Archiving :: Packaging, System :: Installation/Setup', -# 'Topic :: System :: Shells', -# 'Topic :: System :: Software Distribution', -# 'Topic :: Terminals, Utilities', -# ], - - - diff --git a/pexpect/test.env b/pexpect/test.env deleted file mode 100644 index bfba421..0000000 --- a/pexpect/test.env +++ /dev/null @@ -1,27 +0,0 @@ -# Source this file to work on the project. -# You should source this from the project root directory -# in order to make tests work properly. - -export PATH=$PATH:tools/ -export PROJECT_PEXPECT_HOME=`pwd` -export PYTHONPATH=$PROJECT_PEXPECT_HOME:$PYTHONPATH -alias testall="trace.py --missing --count --summary tools/testall.py" - -# -# PEXPECT LICENSE -# -# This license is approved by the OSI and FSF as GPL-compatible. -# http://opensource.org/licenses/isc-license.txt -# -# Copyright (c) 2012, Noah Spurrier <noah@noah.org> -# PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY -# PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE -# COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# diff --git a/pexpect/tests/PexpectTestCase.py b/pexpect/tests/PexpectTestCase.py deleted file mode 100644 index f6dff60..0000000 --- a/pexpect/tests/PexpectTestCase.py +++ /dev/null @@ -1,36 +0,0 @@ - -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import unittest -import sys -import os - -class PexpectTestCase(unittest.TestCase): - def setUp(self): - self.PYTHONBIN = sys.executable - self.original_path = os.getcwd() - newpath = os.path.join (os.environ['PROJECT_PEXPECT_HOME'], 'tests') - os.chdir (newpath) - print '\n', self.id(), - unittest.TestCase.setUp(self) - def tearDown(self): - os.chdir (self.original_path) - diff --git a/pexpect/tests/README b/pexpect/tests/README deleted file mode 100644 index 295632b..0000000 --- a/pexpect/tests/README +++ /dev/null @@ -1,18 +0,0 @@ - -The best way to run these tests is from the directory above this one. Source -the test.env environment file. This will make sure that you are using the -correct pexpect.py file otherwise Python might try to import a different -version if it is already installed in this environment. Then run the testall.py -script in the tools/ directory. This script will automatically build a test -suite from all the test scripts in the tests/ directory. This allows you to add -new test scripts simply by dropping them in the tests/ directory. You don't -have to register the test or do anything else to integrate it into the test -suite. - -For example, this is the normal set of commands you would use to run all tests -in the tests/ directory: - - $ cd /home/user/pexpect_dev/ - $ . test.env - $ ./tools/testall.py - diff --git a/pexpect/tests/TESTDATA.txt b/pexpect/tests/TESTDATA.txt deleted file mode 100644 index adb9c01..0000000 --- a/pexpect/tests/TESTDATA.txt +++ /dev/null @@ -1,8 +0,0 @@ -This is test data. - One - 2 - THREE - IV - ..... - 110 -This is the end of test data: END diff --git a/pexpect/tests/__init__.py b/pexpect/tests/__init__.py deleted file mode 100755 index f717d82..0000000 --- a/pexpect/tests/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ - -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -# __init__.py -# The mere presence of this file makes the dir a package. -pass - diff --git a/pexpect/tests/adhoc.py b/pexpect/tests/adhoc.py deleted file mode 100755 index 8567a71..0000000 --- a/pexpect/tests/adhoc.py +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import pexpect -import time - -p = pexpect.spawn ('./a.out') -print p.exitstatus -p.expect (pexpect.EOF) -print p.before -time.sleep(1) -print 'exitstatus:', p.exitstatus -print 'isalive',p.isalive() -print 'exitstatus',p.exitstatus -print 'isalive',p.isalive() -print 'exitstatus',p.exitstatus - diff --git a/pexpect/tests/bambi.vt b/pexpect/tests/bambi.vt deleted file mode 100644 index 853f099..0000000 --- a/pexpect/tests/bambi.vt +++ /dev/null @@ -1,417 +0,0 @@ -[?25l -[1;24r -[2J -[10;1H The -[10;1H The Adventures -[10;1H The Adventures of -[10;1H The Adventures of BAMBI -[16;1H -[15;1H Number -[15;1H Number One : -[15;1H Number One : BAMBI -[15;1H Number One : BAMBI versus -[15;1H Number One : BAMBI versus GODZILLA -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[16;1H -[2J -[23;5H ,| *./[24;5H\|(/|/[1;1H -[22;38H /|[23;38H |/`|',[24;38H/| \|/[1;1H -[23;65H \/_,| /| /,[24;65H /<|\\/\|/|\[1;1H -[15;1H _^_ -[16;1H o / .\ -[17;1H \,--------; __o -[18;1H / .:::. . / -[19;1H \___________/ -[20;1H |\ |\ -[21;1H | > | \ -[22;1H / / | \ -[15;2H _^_ -[16;2H o / .\ -[17;2H \,--------; __o -[18;2H / .:::. . / -[19;2H \___________/ -[20;2H \| |\ -[21;2H \ | \ -[22;2H / \ / | -[15;3H _^_ -[16;3H o / .\ -[17;3H \,--------; __o -[18;3H / .:::. . / -[19;3H \___________/ -[20;3H \\ \| -[21;3H \\ \ -[22;3H | \ |\ -[15;4H _^_ -[16;4H o / .\ -[17;4H \,--------; __o -[18;4H / .:::. . / -[19;4H \___________/ -[20;4H \\ \| -[21;4H >\ \ -[22;4H / | /| -[15;5H _^_ -[16;5H o / .\ -[17;5H \,--------; __o -[18;5H / .:::.. . / -[19;5H \___________/ -[20;5H |\ |\ -[21;5H | > | \ -[22;5H / / | \ -[15;6H _^_ -[16;6H o / .\ -[17;6H \,--------; __o -[18;6H / .:::.. . / -[19;6H \___________/ -[20;6H \| |\ -[21;6H \ | \ -[22;6H / \ / | -[15;18H -[16;18H -[17;18H--,_^_ -[18;18H. .\ -[19;18H__--___o -[17;18H--_ -[18;18H. \ -[19;18H__ \/| -[20;18H|\( .| -[21;18H| \\ / -[22;18H | " -[17;18H--_ -[18;18H. \ -[19;18H__ \/| -[20;18H|\( .| -[21;18H| \\ / -[22;18H | " -[17;18H--_ -[18;18H. \ -[19;18H__ \/| -[20;18H|\( .| -[21;18H| \\ / -[22;18H | " -[17;18H--_ -[18;18H. \ -[19;18H__ \/| -[20;18H|\( .| -[21;18H| \\ / -[22;18H | " -[17;18H--,_^_ -[18;18H. .\ -[19;18H__--___o -[20;18H|\ -[21;18H| \ -[22;18H | -[15;7H _^_ -[16;7H o / .\ -[17;7H \,--------; __o -[18;7H / .:::.. . / -[19;7H \___________/ -[20;7H \\ \| -[21;7H \\ \ -[22;7H | \ |\ -[15;8H _^_ -[16;8H o / .\ -[17;8H \,--------; __o -[18;8H / .:::.. . / -[19;8H \___________/ -[20;8H \\ \| -[21;8H >\ \ -[22;8H / | /| -[15;9H _^_ -[16;9H o / .\ -[17;9H \,--------; __o -[18;9H / .:::.. . / -[19;9H \___________/ -[20;9H |\ |\ -[21;9H | > | \ -[22;9H / / | \ -[15;10H _^_ -[16;10H o / .\ -[17;10H \,--------; __o -[18;10H / .:::.. . / -[19;10H \___________/ -[20;10H \| |\ -[21;10H \ | \ -[22;10H / \ / | -[15;11H _^_ -[16;11H o / .\ -[17;11H \,--------; __o -[18;11H / .:::.. . / -[19;11H \___________/ -[20;11H \\ \| -[21;11H \\ \ -[22;11H | \ |\ -[15;12H _^_ -[16;12H o / .\ -[17;12H \,--------; __o -[18;12H / .:::.. . / -[19;12H \___________/ -[20;12H \\ \| -[21;12H >\ \ -[22;12H / | /| -[15;13H _^_ -[16;13H o / .\ -[17;13H \,--------; __o -[18;13H / .:::.. . / -[19;13H \___________/ -[20;13H |\ |\ -[21;13H | > | \ -[22;13H / / | \ -[15;14H _^_ -[16;14H o / .\ -[17;14H \,--------; __o -[18;14H / .:::.. . / -[19;14H \___________/ -[20;14H \| |\ -[21;14H \ | \ -[22;14H / \ / | -[15;15H _^_ -[16;15H o / .\ -[17;15H \,--------; __o -[18;15H / .:::.. . / -[19;15H \___________/ -[20;15H \\ \| -[21;15H \\ \ -[22;15H | \ |\ -[15;16H _^_ -[16;16H o / .\ -[17;16H \,--------; __o -[18;16H / .:::.. . / -[19;16H \___________/ -[20;16H \\ \| -[21;16H >\ \ -[22;16H / | /| -[15;17H _^_ -[16;17H o / .\ -[17;17H \,--------; __o -[18;17H / .:::.. . / -[19;17H \___________/ -[20;17H |\ |\ -[21;17H | > | \ -[22;17H / / | \ -[15;29H -[16;29H -[17;29H--,_^_ -[18;29H. .\ -[19;29H__--___o -[17;29H--_ -[18;29H. \ -[19;29H__ \/| -[20;29H|\( .| -[21;29H| \\ / -[22;29H| \" -[17;29H--_ -[18;29H. \ -[19;29H__ \/| -[20;29H|\( .| -[21;29H| \\ / -[22;29H| \" -[17;29H--,_^_ -[18;29H. .\ -[19;29H__--___o -[20;29H|\ -[21;29H| \ -[22;29H| \ -[17;29H--,_^_ -[18;29H. .\ -[19;29H__--___o -[20;29H|\ -[21;29H| \ -[22;29H| \ -[17;29H--_ -[18;29H. \ -[19;29H__ \/| -[20;29H|\( .| -[21;29H| \\ / -[22;29H| \" -[17;29H--_ -[18;29H. \ -[19;29H__ \/| -[20;29H|\( .| -[21;29H| \\ / -[22;29H| \" -[17;29H--_ -[18;29H. \ -[19;29H__ \/| -[20;29H|\( .| -[21;29H| \\ / -[22;29H| \" -[17;29H--,_^_ -[18;29H. .\ -[19;29H__--___o -[20;29H|\ -[21;29H| \ -[22;29H| \ -[15;18H _^_ -[16;18H o / .\ -[17;18H \,--------; __o -[18;18H / .:::.. . / -[19;18H \___________/ -[20;18H \| |\ -[21;18H \ | \ -[22;18H / \ / | -[15;19H _^_ -[16;19H o / .\ -[17;19H \,--------; __o -[18;19H / .:::.. . / -[19;19H \___________/ -[20;19H \\ \| -[21;19H \\ \ -[22;19H | \ |\ -[15;20H _^_ -[16;20H o / .\ -[17;20H \,--------; __o -[18;20H / .:::.. . / -[19;20H \___________/ -[20;20H \\ \| -[21;20H >\ \ -[22;20H / | /| -[15;21H _^_ -[16;21H o / .\ -[17;21H \,--------; __o -[18;21H / .:::.. . / -[19;21H \___________/ -[20;21H |\ |\ -[21;21H | > | \ -[22;21H / / | \ -[15;22H _^_ -[16;22H o / .\ -[17;22H \,--------; __o -[18;22H / .:::.. . / -[19;22H \___________/ -[20;22H \| |\ -[21;22H \ | \ -[22;22H / \ / | -[15;23H _^_ -[16;23H o / .\ -[17;23H \,--------; __o -[18;23H / .:::.. . / -[19;23H \___________/ -[20;23H \\ \| -[21;23H \\ \ -[22;23H | \ |\ -[15;24H _^_ -[16;24H o / .\ -[17;24H \,--------; __o -[18;24H / .:::.. . / -[19;24H \___________/ -[20;24H \\ \| -[21;24H >\ \ -[22;24H / | /| -[15;24H -[16;24H o -[17;24H \,----------,_^_ -[18;24H / .:::.. . .\ -[19;24H \___________--___o -[20;24H \\ \| -[21;24H >\ \ -[22;24H / | /| -[15;24H -[16;24H o -[17;24H \,----------_ -[18;24H / .:::.. . \ -[19;24H \___________ \/| -[20;24H \\ \|( .| -[21;24H >\ \ \ / -[22;24H / | /| " -[1;15r -[1;10H`' `.__________________________________/M -[1;10H( / ([1;54H/M -[1;10H(-.___[1;55H)M -[1;11H/ \/[1;55H)M -[1;12H_______.--'[1;54H\M -[1;23H,____________/[1;53H\M -[1;37H( / )M -[1;37H( ) /M -[1;37H\ \ )M -[1;36H( )M -[1;36H( ( /M -[1;36H\ ( )M -[1;35H( \ )M -[1;35H( ( /M -[1;16r -[1;35H\ ( ) )M -[1;17r -[1;34H( ( / )M -[1;18r -[1;34H( \ ) /M -[1;19r -[1;34H\ ( ) )M -[1;20r -[1;33H( ) )M -[1;21r -[1;33H( ) /M -[1;22r -[1;33H\ / )M -[1;24r -[1;32H( ) ) -[23;25H / > | \ -[1;1H -[1;1H -[10;1H T[10;1H T[10;1H T -[10;1H T H[10;1H T H[10;1H T H -[10;1H T H E[10;1H T H E[10;1H T H E [10;1H T H E -[10;1H T H E E[10;1H T H E E[10;1H T H E E -[10;1H T H E E N[10;1H T H E E N[10;1H T H E E N -[10;1H T H E E N D[10;1H T H E E N D -[11;1H =============== -[22;1H -[?25h diff --git a/pexpect/tests/depricated_test_filedescriptor.py b/pexpect/tests/depricated_test_filedescriptor.py deleted file mode 100755 index f5223f4..0000000 --- a/pexpect/tests/depricated_test_filedescriptor.py +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import pexpect -import unittest -import PexpectTestCase -import sys -import os - -class ExpectTestCase(PexpectTestCase.PexpectTestCase): - def setUp(self): - print self.id() - PexpectTestCase.PexpectTestCase.setUp(self) - - def test_fd (self): - fd = os.open ('TESTDATA.txt', os.O_RDONLY) - s = pexpect.spawn (fd) - s.expect ('This is the end of test data:') - s.expect (pexpect.EOF) - assert s.before == ' END\n' - - def test_maxread (self): - fd = os.open ('TESTDATA.txt', os.O_RDONLY) - s = pexpect.spawn (fd) - s.maxread = 100 - s.expect('2') - s.expect ('This is the end of test data:') - s.expect (pexpect.EOF) - assert s.before == ' END\n' - - def test_fd_isalive (self): - fd = os.open ('TESTDATA.txt', os.O_RDONLY) - s = pexpect.spawn (fd) - assert s.isalive() - os.close (fd) - assert not s.isalive() - - def test_fd_isatty (self): - fd = os.open ('TESTDATA.txt', os.O_RDONLY) - s = pexpect.spawn (fd) - assert not s.isatty() - os.close(fd) - -### def test_close_does_not_close_fd (self): -### '''Calling close() on a pexpect.spawn object should not -### close the underlying file descriptor. -### ''' -### fd = os.open ('TESTDATA.txt', os.O_RDONLY) -### s = pexpect.spawn (fd) -### try: -### s.close() -### self.fail('Expected an Exception.') -### except pexpect.ExceptionPexpect, e: -### pass - -if __name__ == '__main__': - unittest.main() - -suite = unittest.makeSuite(ExpectTestCase, 'test') - -#fout = open('delete_me_1','wb') -#fout.write(the_old_way) -#fout.close -#fout = open('delete_me_2', 'wb') -#fout.write(the_new_way) -#fout.close diff --git a/pexpect/tests/echo_wait.py b/pexpect/tests/echo_wait.py deleted file mode 100755 index db940de..0000000 --- a/pexpect/tests/echo_wait.py +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import signal, time, struct, fcntl, termios, os, sys - -# a dumb PAM will print the password prompt first then set ECHO -# False. What it should do it set ECHO False first then print the -# prompt. Otherwise, if we see the password prompt and type out -# password real fast before it turns off ECHO then some or all of -# our password might be visibly echod back to us. Sounds unlikely? -# It happens. - -print "fake password:" -sys.stdout.flush() -time.sleep(3) -attr = termios.tcgetattr(sys.stdout) -attr[3] = attr[3] & ~termios.ECHO -termios.tcsetattr(sys.stdout, termios.TCSANOW, attr) -time.sleep(12) -attr[3] = attr[3] | termios.ECHO -termios.tcsetattr(sys.stdout, termios.TCSANOW, attr) -time.sleep(2) diff --git a/pexpect/tests/exit1.py b/pexpect/tests/exit1.py deleted file mode 100755 index 4e07377..0000000 --- a/pexpect/tests/exit1.py +++ /dev/null @@ -1,24 +0,0 @@ -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import os, sys - -print "Hello" -sys.stdout.flush() -os._exit(1) diff --git a/pexpect/tests/exit667.c b/pexpect/tests/exit667.c deleted file mode 100644 index 962b9fd..0000000 --- a/pexpect/tests/exit667.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -*/ - -#include <stdio.h> -int main () -{ - printf ("Hello world!\n"); - exit(7); -} diff --git a/pexpect/tests/getch.py b/pexpect/tests/getch.py deleted file mode 100755 index 53ff2c7..0000000 --- a/pexpect/tests/getch.py +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import sys, tty, termios -def getch(): - fd = sys.stdin.fileno() - old_settings = termios.tcgetattr(fd) - try: - tty.setraw(sys.stdin.fileno()) - ch = sys.stdin.read(1) - finally: - termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) - return ch - -#for i in range(256): -# Current Python unicode support was too hard to figure out. -# This only tests the true ASCII characters now: -for i in range(126): - c = getch() - a = ord(c) # chr(a) - print a - diff --git a/pexpect/tests/globe.vt b/pexpect/tests/globe.vt deleted file mode 100644 index 85dc78d..0000000 --- a/pexpect/tests/globe.vt +++ /dev/null @@ -1,690 +0,0 @@ -[H[J _-o#&&*''''?d:>b\_ - _o/"`'' '',, dMF9MMMMMHo_ - .o&#' `"MbHMMMMMMMMMMMHo. - .o"" ' vodM*$&&HMMMMMMMMMM?. - ,' $M&ood,~'`(&##MMMMMMH\ - / ,MMMMMMM#b?#bobMMMMHMMML - & ?MMMMMMMMMMMMMMMMM7MMM$R*Hk - ?$. :MMMMMMMMMMMMMMMMMMM/HMMM|`*L -| |MMMMMMMMMMMMMMMMMMMMbMH' T, -$H#: `*MMMMMMMMMMMMMMMMMMMMb#}' `? -]MMH# ""*""""*#MMMMMMMMMMMMM' - -MMMMMb_ |MMMMMMMMMMMP' : -HMMMMMMMHo `MMMMMMMMMT . -?MMMMMMMMP 9MMMMMMMM} - --?MMMMMMM |MMMMMMMMM?,d- ' - :|MMMMMM- `MMMMMMMT .M|. : - .9MMM[ &MMMMM*' `' . - :9MMk `MMM#" - - &M} ` .- - `&. . - `~, . ./ - . _ .- - '`--._,dd###pp=""' -[H _v->#H#P? "':o<>\_ - .,dP` `'' "'-o.+H6&MMMHo_ - oHMH9' `?&bHMHMMMMMMHo. - oMP"' ' ooMP*#&HMMMMMMM?. - ,M* - `*MSdob//`^&##MMMH\ - d*' .,MMMMMMH#o>#ooMMMMMb - HM- :HMMMMMMMMMMMMMMM&HM[R\ - d"Z\. 9MMMMMMMMMMMMMMMMM[HMM|: --H - MMMMMMMMMMMMMMMMMMMbMP' : -:??Mb# `9MMMMMMMMMMMMMMMMMMH#! . -: MMMMH#, "*""""`#HMMMMMMMMMMH - -||MMMMMM6\. {MMMMMMMMMH' : -:|MMMMMMMMMMHo `9MMMMMMMM' . -. HMMMMMMMMMMP' !MMMMMMMM ` -- `#MMMMMMMMM HMMMMMMM*,/ : - : ?MMMMMMMF HMMMMMM',P' : - . HMMMMR' {MMMMP' ^' - - : `HMMMT iMMH' .' - -.`HMH . - -:*H . ' - -`\,, . .- - ' . _ .-` - '`~\.__,obb#q==~''' -[H .ovr:HMM#?:`' >b\_ - .,:&Hi' `' "' \\|&bSMHo_ - oHMMM#*} `?&dMMMMMMHo. - .dMMMH"'''' ,oHH*&&9MMMM?. - ,MMM*' `*M\bd<|"*&#MH\ - dHH?' :MMMMMM#bd#odMML - H' |\ `dMMMMMMMMMMMMMM9Mk - JL/"7+,. `MMMMMMMMMMMMMMMH9ML --`Hp ' |MMMMMMMMMMMMMMMMHH|: -: \\#M#d? `HMMMMMMMMMMMMMMMMH. -. JMMMMM##, ``*""'"*#MMMMMMMMH --. ,MMMMMMMM6o_ |MMMMMMMM': -: |MMMMMMMMMMMMMb\ TMMMMMMT : -. ?MMMMMMMMMMMMM' :MMMMMM|.` -- ?HMMMMMMMMMM: HMMMMMM\|: - : 9MMMMMMMMH' `MMMMMP.P. - . `MMMMMMT'' HMMM*''- - - TMMMMM' MM*' - - '. HMM# - - -. `9M: .' - -. `b,, . . ' - '-\ ., .-` - '-:b~\\_,oddq==--" -[H _oo##'9MMHb':'-,o_ - .oH":HH$' ""' "' -\7*R&o_ - .oHMMMHMH#9: "\bMMMMHo. - dMMMMMM*""'`' .oHM"H9MM?. - ,MMMMMM' "HLbd<|?&H\ - JMMH#H' |MMMMM#b>bHb - :MH ."\ `|MMMMMMMMMMMM& - .:M:d-"|:b.. 9MMMMMMMMMMMMM+ -: "*H| - &MMMMMMMMMMMMMH: -. `LvdHH#d? `?MMMMMMMMMMMMMb -: iMMMMMMH#b `"*"'"#HMMMMMM -. . ,MMMMMMMMMMb\. {MMMMMH -- |MMMMMMMMMMMMMMHb, `MMMMM| -: |MMMMMMMMMMMMMMH' &MMMM, -- `#MMMMMMMMMMMM |MMMM6- - : `MMMMMMMMMM+ ]MMMT/ - . `MMMMMMMP" HMM*` - - |MMMMMH' ,M#'- - '. :MMMH| .- - . |MM - - ` . `#?.. . ..' - -. _. .- - '-|.#qo__,,ob=~~-'' -[H _ooppH[`MMMD::--\_ - _oHMR":&M&. ""' "' /&\\_ - oHMMMMMHMMH#9, `"<MMHo. - oHMMMMMMMM*""'`` .dMP#M?. - .dMMMMMMMM* `H\do?&\ - -iMMMHH#H' &MMMHb#? - : ZMM' 7-. `{MMMMMMMMH - . .M6_d|"`$|v.. 9MMMMMMMMML -- `'*H# : |MMMMMMMMMM: -: *\\dHM#dd. ?MMMMMMMMMb -- |MMMMMMM##\ `"*""?HMMM -: . |MMMMMMMMMMMo\. {MMM -. {MMMMMMMMMMMMMMMHo. `MMM -- ?MMMMMMMMMMMMMMM*' -MMP -: `#MMMMMMMMMMMMT dMM' - - |MMMMMMMMMMH' -MMT - : `MMMMMMMM"' JMP - - MMMMMMH' ,H? - '. HMMM#' : - . ?MM- . ' - -. *M:.. .- - - . _. .- - '-.~-dHb__\ov+~~-` -[H .oo>#&H6?*MMH:-.._ - .oHMMMR:"&MZ\ `"' " |$-_ - ..dMMMMMMMMdMMM#9\ `'HHo. - . ,dMMMMMMMMMMM"`' ` ?MP?. - . |MMMMMMMMMMM' `"$b&\ - - |MMMMHH##M' HMMH? - - TTMM| >.. \MMMMMH - : |MM\,#-""$~b\. `MMMMMM+ -. ``"H&# - &MMMMMM| -: *\v,#MHddc. `9MMMMMb -. MMMMMMMM##\ `"":HM -- . .HMMMMMMMMMMRo_. |M -: |MMMMMMMMMMMMMMMM#\ :M -- `HMMMMMMMMMMMMMMM' |T -: `*HMMMMMMMMMMMM' H' - : MMMMMMMMMMM| |T - . MMMMMMMM?' ./ - `. MMMMMMH' ./ - -. |MMMH#' . - . `MM* . ' - -. #M: . . .- - ` . ., .- - '-.-~ooHH__,,v~--` -[H _ood>H&H&Z?#M#b-\. - .\HMMMMMR?`\M6b."`' ''``v. - .. .MMMMMMMMMMHMMM#&. ``~o. - . ,HMMMMMMMMMMMM*"'-` &b. - . .MMMMMMMMMMMMH' `"&\ - - RMMMMM#H##R' 4Mb - - |7MMM' ?:: `|MMb - / HMM__#|`"\>?v.. `MMML -. `"'#Hd| ` 9MMM: -- |\,\?HH#bbL `9MMb -: !MMMMMMMH#b, `""T -. . ,MMMMMMMMMMMbo. | -: 4MMMMMMMMMMMMMMMHo | -: ?MMMMMMMMMMMMMMM? : --. `#MMMMMMMMMMMM: .- - : |MMMMMMMMMM? . - - JMMMMMMMT' : - `. MMMMMMH' - - -. |MMM#*` - - . HMH' . ' - -. #H:. .- - ` . .\ .- - '-..-+oodHL_,--/-` -[H _,\?dZkMHF&$*q#b.. - .//9MMMMMMM?:'HM\\"`-''`.. - ..` :MMMMMMMMMMHMMMMH?_ `-\ - . .dMMMMMMMMMMMMMM'"'" `\. - . |MMMMMMMMMMMMMR \\ - - T9MMMMMHH##M" `? - : (9MMM' !':. &k - .: HMM\_?p "":-b\. `ML -- "'"H&#, : |M| -: ?\,\dMH#b#. 9b -: |MMMMMMM##, `* -: . +MMMMMMMMMMMo_ - -: HMMMMMMMMMMMMMM#, : -: 9MMMMMMMMMMMMMH' . -: . *HMMMMMMMMMMP .' - : MMMMMMMMMH' . - - :MMMMMMM'` . - `. 9MMMMM*' - - -. {MMM#' : - - |MM" .' - `. &M'.. . ..' - ' . ._ .- - '-. -voboo#&:,-.-` -[H _oo:\bk99M[<$$+b\. - .$*"MMMMMMMM[:"\Mb\?^" . - . '` HMMMMMMMMMMHMMMM+?. `. - . .HMMMMMMMMMMMMMMP"'' . - . `MMMMMMMMMMMMMM| -`. - - `&MMMMMMHH##H: : - : `(*MMM} `|\ | - : `- ?MMb__#|""`|+v.. \ -. `''*H#b - :| -: `*\v,#M#b#, \ -. 9MMMMMMHb. : -: . #MMMMMMMMMb\ - -- .HMMMMMMMMMMMMb : -: `MMMMMMMMMMMMH . --: . `#MMMMMMMMMP ' - : ]MMMMMMMH' : - - ,MMMMMM?' . - `: HMMMMH" - - -. .HMM#* .- - `. .HH*' . - `-. &R". .- - -. ._ .- - '-. .voodoodc?..-` -[H _\oo\?ddk9MRbS>v\_ - ..:>*""MMMMMMMMM:?|H?$?-. - ..- - "HMMMMMMMMMMHMMMH\_-. - . dMMMMMMMMMMMMMMT" . - . TMMMMMMMMMMMMMM `. - - `&HMMMMMM#H#H: . - - `\7HMMH |\. . - : ` HMM\_?c`""+?\.. : -- "``#&#| . - -: `?,\#MHdb. . -: |MMMMMH#. : -: . ,HMMMMMMMb, - -: ' 4MMMMMMMMMMH` -: . 9MMMMMMMMMT- -:.` `#MMMMMMMH ' - : ' HMMMMMH': - - |MMMMH" - - `: |MMMH*' .' - '? dMM#' . - \. .dH" .' - -. ,M'- ..' - ` . .. ..-` - '-. .\ooooboo<^.-` -[H _o,:o?\?dM&MHcc~,. - ..^':&#""HMMMMMMMM$:?&&?. - .` -` 'HMMMMMMMMMHMMMp\. - . ' |MMMMMMMMMMMMMM"' . - . `9MMMMMMMMMMMMM -. - - `*9MMMMMHH##[ . - - `\Z9MMM `~\ . - : '| ?MMb_?p""-?v.. : -- `"'*&#, - . -: `?,oHH#? . --- |MMMMH,: -: . |MMMMMM6, -: - |MMMMMMMM -? HMMMMMMP --- . ' |HMMMMM' - :.` . ' JMMMM+ - \ ,MMMP: - : |MMH?: - -:\. dM#" . - \ ,H*' .' - -. d':..' - ` . .,.- - '-.. .\oooodov~^-` -[H _o\:,??\??MR9#cb\_ - .v/''':&#""#HMMMMMMM$?*d\. - ..~' - -` `"#MMMMMMMMMMMHv. - .-' HMMMMMMMMMMMR!. - : `9MMMMMMMMMMM| -. - . `*9MMMMMH##| . - - `(#MMH `:, . - : '| `HMb_>/"|\,.: -.' `"'#&b - . -: ?\oHH?. -: !MMM& -: . . HMMMM -/. - -MMMMM -\`. 9MMMP -:. . . - |MMM' - \... ' .MMT - &. .dMP - \, .HM* - \. `\. ,H&' - `- `| - ,&': - `. ,/\ ' - '-.. _.- - "---.._\o,oov+--'" -[H _,d?,:?o?:?HM>#b\_ - ..H*"''`'H#*"**MMMMMM6$$v_ - v//" - `` `'#MMMMMMMMHo. - /"` |MMMMMMMMMM:. - ,> `HMMMMMMMMH:. - : `#HMMMMHH\ - - ' `Z#MM, `,: - : '\ ?HH_>:`\, -: "'*&| `: -. <\Hb -: MM -: . iMM -Mb\. {MM -::.`- - !MP -`&. . . - :M' - 9H, \ ' |T - HM? ,P - *ML ?? - :&. `o .d' - ': |T /" - -. .<'' - `... ..- - "`-=.,_,,,oov-~.-` -[H _,oc>?_:b?o?HH#b\_ - .v/99*""" '*H#""*HMMMMMZ,_ - oH* /" - ' "`#MMMMM#o. - ./*>- `MMMMMMMb - ,b/' `#MMMMMMM\ - :' ``HMMMMb: - /- `|&MH `\ - / `-. |Hb??\ -,- ' "`&,. -1 \} -!. T -$,. . 1 -?`M??. M -?.::| '\ - ? - M?&. . . - ,' - 9MMH\ .. ' ` . - HMMM#. :' - 9#MMb .. - -:"# `b. .- - . ` {! / - - ,-' - ' . .- - ```^==\_.,,,ov--\-` -[H _\o##??,:io??$#b\_ - .oH#"H9*""" "`#H*"*#MMMHo_ - oHMM- -' - '' ``*HMMHo. - dM#S>-` ?MMMM?. - ,&&,/' "#MMMH\ - d?-" `*HMMb - H? "ZHb: - /: \ H?L -|:| . `*: -:?: \ ->" : -M|\,_ | -!|":HH?-'. : -:^'_:?"\ `-- - . -- |ML?b . .. - - - :HMMMMH\ \ ` : - >MMMMMM#. . - ^M*HMMM| - - `. `"#+ `?v .` - . `- +?' - - ` . ..' - - . .- - "`\b=p?.._\\vv---` -[H _,o#bH\??::?o?cbo_ - .o#MH#**SH""' "`*H#"*#MHo_ - oHMMMH^ ^" - ` '*HHo. - .dMMM#">>- `HM?. - ,MH:R_o/ `*MH\ - dMM' ' "ML - HMR! ' `#k - d&'. -. `L -:M :: ` `- -/| !| - -k.$-" : -}9R:!,,_. . -\::\':`*M#\-'. - -: "''..:"!`\ '- - ` -- ,HMb.H| . _ - .' - : ,MMMMMMMb. .. . - .`HMMMMMMMM? . - `.`9M#*HMMMM : - -.' "##* `b, . - . ` ,/' .' - ` . ..' - - . ..- - "`*#d##c.._\v----` -[H _,o#&oHb?\o::d?>\_ - .oHHMMM#**$M""` "`*HH"#&o_ - oHMMMMMMD' .'' - ' ``bo. - .dMMMMMH*'/|- `\b. - ,MMMM?T|_o/ `\\ - dMMMMP '' `| - HMMMH& - `\ - /MH7' : -- : --:MM {. . . -:i?' .!& . -:{, o| ' : --T?9M\:-'o,_ . -: \?::``"`?9MHo./.. - -. '"`'^ _.`"!"^. `- - ` -- ,bMM?.M\ . . - . .' - : .oMMMMMMMMb. .. ` . - . `HMMMMMMMMMMb - - - 9MH*#HMMMMH .' - '. ' `"*##' `b. : - . ` .d'' .' - -. . ' - -. .-` - "`*##H###:._\--.-` -[H _oo#H&d#b?\b:_>>\_ - .oHMMMMMMH*"*9R"'-``*#P\-_ - oHMMMMMMMMM$ ." ' `^- - .dMMMMMMMMH*",?- '\. - ,MMMMMMM:?}.,d' `. - dMMMMMMMH /'' : - HMMMMMMM&' - - - dPTMMP>' : -. : -|? -MM} .\ . -J' ::*' -$L . -: ?b .,H- ' : -- |6.&MP:: !.,_. - -: `\:: "' "`:"MM#,-^, - : -- ````:' _.:"?``\ `- . -: .?bMML.]# - _ ` . .' - - .o#MMMMMMMMH\ \. . . - - `HMMMMMMMMMMMH : - `. `HMM#*#MMMMMH' - - -. ' ``##*' i+ : - - `' v/' .' - `- ..' - ' . .- - "`*##HMH##:__,-.-` -[H _oo##Mbb&bo??o_>\_ - .oHMMMMMMMMM**#?M*' "?*&.. - oHMMMMMMMMMMMM4 `" - `. - .dMMMMMMMMMMMM#"\?.- . - ,MMMMMMMMMM}"9:_,d' -. - dMMMMMMMMMMM| ^'' . - &MMMMMMMMMMH\ - . - :{M*"MMMPT"' : `-. : -.'M' 'MMM. -T, . . -- k i:?'' -|& . -: ` -o& .,H- " : -- `M:`HMP|:'!.o._. . -: "<:::'<^ '"``9MH#,-^ . - -- '''``''._.`"?`^| ^ - : -: ?#dMM_.M? . . - ..' - : ,ddMMMMMMMMMb. .. ' . - . TMMMMMMMMMMMMM, : - - ?MMH**#MMMMMH' : - '. ' "`##*' &. : - -. `' ,~" .' - -. ..' - ` . .- - ```*##HMMMH#<:,..-` -[H _,dd#HMb&dHo?\?:\_ - .oHMMMMMMMMMMMH***9P'`"\v. - oHMMMMMMMMMMMMMMM> `' -. - .dMMMMMMMMMMMMMMMH*'|~-' . - ,MMMMMMMMMMMMM6>`H._,& -. - dMMMMMMMMMMMMMMM| `" . - H*MMMMMMMMMMMMMH&. - . - d' HMM""&MMMPT'' :. `.- -,' MP `TMMM, |: . - -| #: ? *" : &L : -! `' /?H ,#r `' : -. ?M: HMM^<~->,o._ : -: `9:::'`*-``':`9MHb,|-, ' : -. `"''':' :_ ""!"^. `| : -`. _dbHM6_|H. . . ' .' - \ _odHMMMMMMMMH, .. ` : - `- |MMMMMMMMMMMMM| : - `. 9MMH**#MMMMMH' : - -. ' "?##" d : - . ' ,/" .' - `.. ..' - ` . .- - '`"#HHMMMMM#<>..-` -[H _oo##bHMb&d#bd,>\_ - .oHMMMMMMMMMMMMMM***9R"-.. - oHMMMMMMMMMMMMMMMMMH\ ? `-. - .dMMMMMMMMMMMMMMMMMMM#".}-' . - ,MMMMMMMMMMMMMMMMM6/`H _o} -. - dMMMMMMMMMMMMMMMMMMML `'' . - HbP*HMMMMMMMMMMMMMMM*: - , - dMH' `MMMP'"HMMMR'T" : : -|H' -MR' `?MMMb P, . . -1& *| |.`*" .-`&| . -M' " |\&| .,#~ "' : -T :HL.|HMH\c~`|v,\_ : -| `"|:::':`-`` '"MM#\-'. -: -% ``'``'`' :_ '?'`| ``. : -||, ,#dMM?.M? . .` - - ?\ .,odMMMMMMMMM? \ ` : - / |MMMMMMMMMMMMM: .' - `. TMMH#*9MMMMM* : - -. ` "*#*' ,: . - . ` .v'' .' - `. ..' - '- . .- - "`\+HHMMMMMMHr~.-` -[H _,,>#b&HMHd&&bb>\_ - _oHMMMMMMMMMMMMMMMMH**H:. - oHMMMMMMMMMMMMMMMMMMMM#v`? `. - .dMMMMMMMMMMMMMMMMMMMMMMH*`+| . - ,MMMMMMMMMMMMMMMMMMMMMb|?+.,H -. - ddHMMMMMMMMMMMMMMMMMMMMMb `' . - HMMkZ**HMMMMMMMMMMMMMMMMH\ - . : - dTMMM* `9MMMP'"*MMMMPT"` .. : -|M6H'' 4MP' `"HMMM| !|. . . -1MHp' #L $ *"' .-:&. . -MMM' " q:H. .o#-``' : -MM' ?H?.|MMH::::-o,_. - -M[ `*?:::'|` `"`:9MH\~-. ` -&M. ""'`'^'.:.`?'`. '| -: -`M|d, .dbHM[.1? .. : - 9||| . _obMMMMMMMMH, . : - H.^ MMMMMMMMMMMM} - - \ |MMH#*HMMMMH' .' - . ` `#*' ,:- - ` '' .-'. - `. .- - '- . .-` - '`\bqHMMMMMMHHb--` -[H .,:,#&6dHHHb&##o\_ - .oHHMMMMMMMMMMMMMMMMMH*\,. - oHMMMMMMMMMMMMMMMMMMMMMMHb:'-. - .dMMMMMMMMMMMMMMMMMMMMMMMMMH|\/' . - ,&HMMMMMMMMMMMMMMMMMMMMMMM/"&.,d. -. - dboMMHMMMMMMMMMMMMMMMMMMMMMML `' . - HMHMMM$Z***MMMMMMMMMMMMMMMMMM|.- . - dMM}MMMM#' `9MMMH?"`MMMMR'T' _ : -|MMMbM#'' |MM" ``MMMH. <_ . -dMMMM#& *&. .?`*" .'&: . -MMMMMH- `' -v/H .dD "' ' : -MMMM* `*M: 4MM*::-!v,_ : -MMMM `*?::" "'``"?9Mb::. : -&MMM, `"'"'|"._ "?`| - : -`MMM}.H ,#dM[_H ..: - 9MMi`M: . .ooHMMMMMMM, .. - 9Mb `- 1MMMMMMMMMM| : - ?M |MM#*#MMMM* . - -. ` |#"' ,' - . -" v` - -. .- - - . . ` - '-*#d#HHMMMMHH#"-' -[H _,<_:&S6dHHHb&bb\_ - .odHMMMMMMMMMMMMMMMMMMM}-_ - .oHMMMMMMMMMMMMMMMMMMMMMMMM#d:. - ?9MMMMMMMMMMMMMMMMMMMMMMMMMMMH-$ . - ,::dHMMMMMMMMMMMMMMMMMMMMMMMMH:\.?? -. - dMdboHMMHMMMMMMMMMMMMMMMMMMMMMMH, ' . - HMMMM7MMMb$R***MMMMMMMMMMMMMMMMMH\ - . - dMMMMM/MMMMM* `$MMMM*'"*MMMM?&' . : -|MMMMMMb1H*' HMP' '9MMM| &. . . -dMMMMMMM##~` `#\ |.`*" .-9. : -9MMMMMMMM* ` |v7? .,H `' ` : -SMMMMMMH' '9M_-MMH::-\v_ : -:HMMMMM `\_:"'|'`':9Mv\. --|MMMMM, ""`'`':.`?\ \ -`:MMMMM}.d} .?bM6,| | - :?MMM6 M| . .,oHMMMMM| / - .?MMM- `' &MMMMMMMM|. - -`HM- HMH#*MMM?: - '. ' `#*:` - - -'/ - ` . . ' - ` . . ` - '--##HH#HMMMHH#""` -[H _o,d_?dZdoHHHb#b\_ - .vdMMMMMMMMMMMMMMMMMMMMH\. - .,HHMMMMMMMMMMMMMMMMMMMMMMMMH&,. - /?RMMMMMMMMMMMMMMMMMMMMMMMMMMMMH|.. - ,\?>`T#RMMMMMMMMMMMMMMMMMMMMMMMM6`\|/ - dMMbd#ooHMMMHMMMMMMMMMMMMMMMMMMMMMH,`' ' - HMMMMMMMTMMMMb$ZP**HMMMMMMMMMMMMMMMM|. : - dMMMMMMMM}$MMMMMH' `HMMMH?"`MMMM?T' . : -|MMMMMMMMMMoMH*'' `MM? ``MMM| +\ . -1MMMMMMMMMMMb#/ ?#? |`#" -T: : -*'HMMMMMMMMMM*' " ~?& .?} ' ' . -- 4MMMMMMMMP" `M? HMTc:\\.: -: `MMMMMMM[ "#:::`>`"?M{ -. |MMMMMMH. ``'``'_`:- -- |MMMMMMM|.dD ,#Mb\' - : *MMMMM: iM| . _oHMMMM: - . ?MMMM' "' ,MMMMMMP - : `HMH JM#*MMT - -. ' ` #' - . / - -. - .' - -. . ` - '--=&&MH##HMHH#""" -[H .-:?,Z?:&$dHH##b\_ - ,:bqRMMMMMMMMMMMMMMMMMHo. - .?HHHMMMMMMMMMMMMMMMMMMMMMMMHo. - -o/*M9MMMMMMMMMMMMMMMMMMMMMMMMMMMv - .:H\b\'|?#HHMMMMMMMMMMMMMMMMMMMMMM6?Z\ - .?MMMHbdbbodMMMMHMMMMMMMMMMMMMMMMMMMM\': - :MMMMMMMMMMM7MMMMb?6P**#MMMMMMMMMMMMMMM_ : - \MMMMMMMMMMMMb^MMMMMM? `*MMMM*"`MMMR<' . - -.1MMMMMMMMMMMMMb]M#"" 9MR' `?MMb \. : --MMMMMMMMMMMMMMMH##|` *&. |`*' .\ . --?""*MMMMMMMMMMMMM' ' |?b ,}" : -: MMMMMMMMMMH' `M_|M}r\? -. `MMMMMMMMM' `$_:`'"H -- TMMMMMMMM, '"``:: -: {MMMMMMMM| oH| .#M- - : `9MMMMMM' .MP . ,oMMT - . HMMMMP' `' ,MMMP - - `MMH' HH9* - '. ` ` .' - - . ' - ` . - .- - ` . .- - ' -==pHMMH##HH#""" -[H _..-:b&::&?&&##bo_ - ...?-#&9MMMMMMMMMMMMMMMHo_ - .. .1&#MMHMMMMMMMMMMMMMMMMMMMHo. - . .o/##R9MMMMMMMMMMMMMMMMMMMMMMMM?. - .- |MSd?|'`$?#HMMMMMMMMMMMMMMMMMMMMMH\ - - dMMMMHbd##oodMMMM#MMMMMMMMMMMMMMMMMH: - - JMMMMMMMMMMMMM7HMMMH$SR***MMMMMMMMMMMMb> - : {MMMMMMMMMMMMMMM`9MMMMMH' ``HMMM?"*MM[| : -- |MMMMMMMMMMMMMMMMM<MH*'' `MM' 'HM? |. -: `MMMMMMMMMMMMMMMMMM##H-' `#, ` |`? /| -. ?"""?HMMMMMMMMMMMMMH' " v& .}? -- |MMMMMMMMMMMP' `H:&H& -i `9MMMMMMMMMT `|?"? -: MMMMMMMMMH "`\ -: MMMMMMMMMH-.dH ,| - : ?MMMMMMM? {M' . .dT - . ?MMMMMR' `' ,MP - - `HMM#' .&* - '. ' `. - - . ' - `.. .- - -. .- - '-.==p##HMMHp&#""" -[H _v---:?&?:?&?&#b\_ - ..' i: #M$MMMMMMMMMMMMMHo_ - .. -]M#HMHMMMMMMMMMMMMMMMMMHo. - . ooP*&6&MMMMMMMMMMMMMMMMMMMMM?. - . - &Rbbd-/`?:##HMMMMMMMMMMMMMMMMMH? - - ,HMMMMM#od#boodMMMMHMMMMMMMMMMMMMMb - - iMMMMMMMMMMMMMMM[*MMMH&$R***MMMMMMMMMb - : |MMMMMMMMMMMMMMMMML"MMMMMM' ``MMMP"HMM: -. HMMMMMMMMMMMMMMMMMMb/MH"" `MR *M,| -: TMMMMMMMMMMMMMMMMMMMMd#&` `D. ?|\ -. `*"'"*HMMMMMMMMMMMMMMP' ' -d,J -: |MMMMMMMMMMMMP' ||M -M, ?MMMMMMMMMM| `\? -&| HMMMMMMMMM} `` -`L .MMMMMMMMMMP ,d| : - *. ?MMMMMMMF' .MP / - | TMMMMMM' `"' / - `. `MMMP' ./ - -. ` . - . . ' - - . .- - -\ ..- - '-..=p####HMH&=""" -[H _vo~^'':&b::d,#b\_ - ..`" `:v +9P]MMMMMMMMMMHo_ - ,- ?Mb#MMMMMMMMMMMMMMMMMHo. - . " ,ooM*&&&HMMMMMMMMMMMMMMMMHb. - . - 99Soo?|'`*?##HMMMMMMMMMMMMMH\ - - .HMMMMMM#od#boodMMMMHMMMMMMMMMMb - - :MMMMMMMMMMMMMMMM67HMMH&$R**HMMMMMb - : .MMMMMMMMMMMMMMMMMMM/HMMMMM| `9MM'HL -: {MMMMMMMMMMMMMMMMMMMM\MM*'' `H[ `9| -| `HMMMMMMMMMMMMMMMMMMMMb##| `F. :? -H `"*"'"`#MMMMMMMMMMMMMMM? ' k -M. MMMMMMMMMMMMM"' H -MMH. `HMMMMMMMMMM: | -&MM| `MMMMMMMMMM, - -`MM| dMMMMMMMMMM|.oH : - 9ML `HMMMMMMM? dH' - - Hi |MMMMMMP "' .' - T. `MMM#' - - `. ` .` - ` - - `.. . ..' - ... .- - '-. //######M#b~"" -[H _ooq=""''$b$_&?b\_ - .-`^" "'o |&M:MMMMMMMMHo_ - o/' -$Mb#MMMMMMMMMMMMMMHo. - /' .ooHP*&R&MMMMMMMMMMMMMM?. - .' `MRbod?|'`+?##9MMMMMMMMMH\ - .` .,MMMMMMH#od##obdMMMMHMMMMMMb - - ?MMMMMMMMMMMMMMMMM$HMMH$ZP*HMMb - ? |MMMMMMMMMMMMMMMMMMM|9MMMMP "M6\ -.- dMMMMMMMMMMMMMMMMMMMMb]M*' |R | -1| `HMMMMMMMMMMMMMMMMMMMMMd#| ?,: -MH, ``*""'"*#MMMMMMMMMMMMMM* '` -MM6_ |MMMMMMMMMMMMH" : -MMMMMb. "MMMMMMMMMMT - -&MMMMM' |MMMMMMMMMH ` -!MMMMb .HMMMMMMMMM+.?& : - TMMMM *MMMMMMMP dH' . : - 9MM' `MMMMMMP' "' . - 9ML `MMM#' - - `H ` : - `\. .' - `-\ . .- - ' ._ .-` - '-\. ,b#####p&**^` diff --git a/pexpect/tests/interact.py b/pexpect/tests/interact.py deleted file mode 100755 index c37c6d9..0000000 --- a/pexpect/tests/interact.py +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import pexpect -p = pexpect.spawn('cat') -p.interact() diff --git a/pexpect/tests/pexpectTest.py b/pexpect/tests/pexpectTest.py deleted file mode 100755 index 62ac422..0000000 --- a/pexpect/tests/pexpectTest.py +++ /dev/null @@ -1,67 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import os, time, pexpect, sys - -def getProcessResults(cmd, timeLimit=20): - ''' - executes 'cmd' as a child process and returns the child's output, - the duration of execution, and the process exit status. Aborts if - child process does not generate output for 'timeLimit' seconds. - ''' - output = "" - startTime = time.time() - child = pexpect.spawn(cmd, timeout=10) - child.logfile = sys.stdout - - while 1: - try: - # read_nonblocking will add to 'outout' one byte at a time - # newlines can show up as '\r\n' so we kill any '\r's which - # will mess up the formatting for the viewer - output += child.read_nonblocking(timeout=timeLimit).replace("\r","") - except pexpect.EOF, e: - print str(e) - # process terminated normally - break - except pexpect.TIMEOUT, e: - print str(e) - output += "\nProcess aborted by FlashTest after %s seconds.\n" % timeLimit - print child.isalive() - child.kill(9) - break - - endTime = time.time() - child.close(force=True) - - duration = endTime - startTime - exitStatus = child.exitstatus - - return (output, duration, exitStatus) - -cmd = "./ticker.py" - -result, duration, exitStatus = getProcessResults(cmd) - -print "result: %s" % result -print "duration: %s" % duration -print "exit-status: %s" % exitStatus - diff --git a/pexpect/tests/platform_tests/CSIGNALTEST/test.c b/pexpect/tests/platform_tests/CSIGNALTEST/test.c deleted file mode 100644 index 86bcc17..0000000 --- a/pexpect/tests/platform_tests/CSIGNALTEST/test.c +++ /dev/null @@ -1,90 +0,0 @@ -/* I built this with "gcc -lutil test.c -otest" */ -#include <sys/types.h> /* include this before any other sys headers */ -#include <sys/wait.h> /* header for waitpid() and various macros */ -#include <signal.h> /* header for signal functions */ -#include <stdio.h> /* header for fprintf() */ -#include <unistd.h> /* header for fork() */ -#ifdef LINUX -#include <pty.h> -#else -#include <util.h> /* header for forkpty, compile with -lutil */ -#endif - -void sig_chld(int); /* prototype for our SIGCHLD handler */ - -int main() -{ - struct sigaction act; - int pid; - int fdm; - char slave_name [20]; - - - /* Assign sig_chld as our SIGCHLD handler. - We don't want to block any other signals in this example - We're only interested in children that have terminated, not ones - which have been stopped (eg user pressing control-Z at terminal). - Finally, make these values effective. If we were writing a real - application, we would save the old value instead of passing NULL. - */ - act.sa_handler = sig_chld; - sigemptyset(&act.sa_mask); - act.sa_flags = SA_NOCLDSTOP; - if (sigaction(SIGCHLD, &act, NULL) < 0) - { - fprintf(stderr, "sigaction failed\n"); - return 1; - } - - /* Do the Fork thing. - */ - pid = forkpty (&fdm, slave_name, NULL, NULL); - /* pid = fork(); */ - - switch (pid) - { - case -1: - fprintf(stderr, "fork failed\n"); - return 1; - break; - - case 0: /* Child process. */ - printf ("This child output will cause trouble.\n"); - _exit(7); - break; - - default: /* Parent process. */ - sleep(1); - printf ("Child pid: %d\n", pid); - sleep(10); /* let child finish -- crappy way to avoid race. */ - break; - } - - return 0; -} - -void sig_chld(int signo) -{ - int status, wpid, child_val; - - printf ("In sig_chld signal handler.\n"); - - /* Wait for any child without blocking */ - wpid = waitpid (-1, & status, WNOHANG); - printf ("\tWaitpid found status for pid: %d\n", wpid); - if (wpid < 0) - { - fprintf(stderr, "\twaitpid failed\n"); - return; - } - printf("\tWaitpid status: %d\n", status); - - if (WIFEXITED(status)) /* did child exit normally? */ - { - child_val = WEXITSTATUS(status); - printf("\tchild exited normally with status %d\n", child_val); - } - printf ("End of sig_chld.\n"); -} - - diff --git a/pexpect/tests/platform_tests/README b/pexpect/tests/platform_tests/README deleted file mode 100644 index c4b0564..0000000 --- a/pexpect/tests/platform_tests/README +++ /dev/null @@ -1,4 +0,0 @@ -These are tests that are not yet pyunit tests -or are not intended to be pyunit tests. -Anything not part of the Python unittest framework -should go here. diff --git a/pexpect/tests/platform_tests/pexqa.py b/pexpect/tests/platform_tests/pexqa.py deleted file mode 100644 index 0ba1412..0000000 --- a/pexpect/tests/platform_tests/pexqa.py +++ /dev/null @@ -1,39 +0,0 @@ -import os, sys -import select -import signal -import traceback -import time -import re -import struct -from types import * -import posix - -import pty -import tty -import termios -import fcntl -class s: - def __init__(self, command, args=None, timeout=30): - - self.pid = self.child_fd = None - try: - #self.pid, self.child_fd = posix.forkpty() - self.pid, self.child_fd = pty.fork() - except OSError, e: - raise Exception('pty fork() failed: ' + str(e)) - - if self.pid == 0: # Child - os.execvp(command, args) - - # Parent - - -print '1' -x = s('ls', ['ls']) -time.sleep(5) -print '2' -result = os.read (x.child_fd, 5555) -print '3' -print result -print '4' - diff --git a/pexpect/tests/platform_tests/test.py b/pexpect/tests/platform_tests/test.py deleted file mode 100755 index f80263b..0000000 --- a/pexpect/tests/platform_tests/test.py +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env python -import signal, os, time, errno, pty - -def signal_handler (signum, frame): - print 'Signal handler called with signal:', signum - print 'signal.SIGCHLD=', signal.SIGKILL - -# First thing we do is set up a handler for SIGCHLD. -signal.signal (signal.SIGCHLD, signal.SIG_IGN) - -print 'PART 1 -- Test signal handling with empty pipe.' -# Create a child process for us to kill. -try: - pid, fd = pty.fork() -except Exception, e: - print str(e) - -if pid == 0: -# os.write (sys.stdout.fileno(), 'This is a test.\n This is a test.') - time.sleep(10000) - -print 'Sending SIGKILL to child pid:', pid -os.kill (pid, signal.SIGKILL) - -# SIGCHLD should interrupt sleep. -# Note that this is a race. -# It is possible that the signal handler will get called -# before we try to sleep, but this has not happened yet. -# But in that case we can only tell by order of printed output. -print 'Entering sleep...' -try: - time.sleep(10) -except: - print 'sleep was interrupted by signal.' - -# Just for fun let's see if the process is alive. -try: - os.kill(pid, 0) - print 'Child is alive. This is ambiguous because it may be a Zombie.' -except OSError, e: - print 'Child appears to be dead.' - -print 'PART 2 -- Test signal handling with full pipe.' -# Create a child process for us to kill. -try: - pid, fd = pty.fork() -except Exception, e: - print str(e) - -if pid == 0: - os.write (sys.stdout.fileno(), 'This is a test.\n This is a test.') - time.sleep(10000) - -print 'Sending SIGKILL to child pid:', pid -os.kill (pid, signal.SIGKILL) - -# SIGCHLD should interrupt sleep. -# Note that this is a race. -# It is possible that the signal handler will get called -# before we try to sleep, but this has not happened yet. -# But in that case we can only tell by order of printed output. -print 'Entering sleep...' -try: - time.sleep(10) -except: - print 'sleep was interrupted by signal.' - -# Just for fun let's see if the process is alive. -try: - os.kill(pid, 0) - print 'Child is alive. This is ambiguous because it may be a Zombie.' -except OSError, e: - print 'Child appears to be dead.' - diff --git a/pexpect/tests/platform_tests/test2.py b/pexpect/tests/platform_tests/test2.py deleted file mode 100755 index 9611f39..0000000 --- a/pexpect/tests/platform_tests/test2.py +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env python -import signal, os, time, errno - -def signal_handler (signum, frame): - print 'Signal handler called with signal:', signum - print 'signal.SIGCHLD=', signal.SIGKILL - -# Create a child process for us to kill. -pid = os.fork() -if pid == 0: - time.sleep(10000) - -#signal.signal (signal.SIGCHLD, signal.SIG_IGN) -signal.signal (signal.SIGCHLD, signal_handler) - -print 'Sending SIGKILL to child pid:', pid -os.kill (pid, signal.SIGKILL) - -# SIGCHLD should interrupt sleep. -# Note that this is a race. -# It is possible that the signal handler will get called -# before we try to sleep, but this has not happened yet. -# But in that case we can only tell by order of printed output. -interrupted = 0 -try: - time.sleep(10) -except: - print 'sleep was interrupted by signal.' - interrupted = 1 - -if not interrupted: - print 'ERROR. Signal did not interrupt sleep.' -else: - print 'Signal interrupted sleep. This is good.' - -# Let's see if the process is alive. -try: - os.kill(pid, 0) - print 'Child is alive. This is ambiguous because it may be a Zombie.' -except OSError, e: - print 'Child appears to be dead.' - diff --git a/pexpect/tests/platform_tests/test_badfork.py b/pexpect/tests/platform_tests/test_badfork.py deleted file mode 100755 index c0768a4..0000000 --- a/pexpect/tests/platform_tests/test_badfork.py +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env python -import pexpect -import pyunit - -def main (): - pid, fd = fooork ('aThelaDSjd','-i') - print 'pid', pid - print 'fd', fd - Xexpect(fd, 'bash.*#',10) - os.write(fd, 'scp -P 6666 *.py noah@gw.tiered.com:pexpect/\n') - Xexpect(fd, 'bash.*#',10) - os.write(fd, 'exit\n') - print _my_read (fd, 1000, 5) - sys.exit (1) - diff --git a/pexpect/tests/platform_tests/test_control_terminal.py b/pexpect/tests/platform_tests/test_control_terminal.py deleted file mode 100755 index 9598fd7..0000000 --- a/pexpect/tests/platform_tests/test_control_terminal.py +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env python - -import termios, fcntl, struct, os, sys - -def getwinsize(): - s = struct.pack("HHHH", 0, 0, 0, 0) - x = fcntl.ioctl(sys.stdout.fileno(), termios.TIOCGWINSZ, s) - rows, cols = struct.unpack("HHHH", x)[:2] - return rows, cols - -def setwinsize(r,c): - # Assume ws_xpixel and ws_ypixel are zero. - s = struct.pack("HHHH", r,c,0,0) - x = fcntl.ioctl(sys.stdout.fileno(), termios.TIOCSWINSZ, s) -print 'stdin tty:', os.ttyname(0) -print 'stdout tty:', os.ttyname(1) -print 'controlling terminal:', os.ctermid() -print 'winsize %d,%d' % getwinsize() -print 'ENDTEST' diff --git a/pexpect/tests/platform_tests/test_handler.py b/pexpect/tests/platform_tests/test_handler.py deleted file mode 100755 index d9239b6..0000000 --- a/pexpect/tests/platform_tests/test_handler.py +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env python -import signal, os, time, errno, pty, sys, fcntl, tty -GLOBAL_SIGCHLD_RECEIVED = 0 - -def nonblock (fd): - # if O_NDELAY is set read() returns 0 (ambiguous with EOF). - # if O_NONBLOCK is set read() returns -1 and sets errno to EAGAIN - original_flags = fcntl.fcntl (fd, fcntl.F_GETFL, 0) - flags = original_flags | os.O_NONBLOCK - fcntl.fcntl(fd, fcntl.F_SETFL, flags) - return original_flags - -def signal_handler (signum, frame): - print '<HANDLER>' - global GLOBAL_SIGCHLD_RECEIVED - status = os.waitpid (-1, os.WNOHANG) - if status[0] == 0: - print 'No process for waitpid:', status - else: - print 'Status:', status - print 'WIFEXITED(status):', os.WIFEXITED(status[1]) - print 'WEXITSTATUS(status):', os.WEXITSTATUS(status[1]) - GLOBAL_SIGCHLD_RECEIVED = 1 - -def main (): - signal.signal (signal.SIGCHLD, signal_handler) - pid, fd = pty.fork() - if pid == 0: - os.write (sys.stdout.fileno(), 'This is a test.\nThis is a test.') - time.sleep(10000) - nonblock (fd) - tty.setraw(fd) #STDIN_FILENO) - print 'Sending SIGKILL to child pid:', pid - time.sleep(2) - os.kill (pid, signal.SIGKILL) - - print 'Entering to sleep...' - try: - time.sleep(2) - except: - print 'Sleep interrupted' - try: - os.kill(pid, 0) - print '\tChild is alive. This is ambiguous because it may be a Zombie.' - except OSError, e: - print '\tChild appears to be dead.' -# print str(e) - print - print 'Reading from master fd:', os.read (fd, 1000) - - - -if __name__ == '__main__': - main () diff --git a/pexpect/tests/platform_tests/test_killed_pid.py b/pexpect/tests/platform_tests/test_killed_pid.py deleted file mode 100755 index ff2fe5e..0000000 --- a/pexpect/tests/platform_tests/test_killed_pid.py +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env python -import os, time, signal -import expyct - -e = expyct.expyct ('/bin/sh', '-i') -print 'pid,fd:', e.pid, e.fd -print 'isAlive:', e.isAlive() -# Treat it brusquely. -print 'sending SIGKILL...' -os.kill (e.pid, signal.SIGKILL) -time.sleep (1) -print os.read(e.fd, 1000) -print 'isAlive:', e.isAlive() -e.expect('\#') -e.send ('ls -la /\n') -r,m,i = e.expect ('\#') -print r diff --git a/pexpect/tests/platform_tests/test_middle_buffer.py b/pexpect/tests/platform_tests/test_middle_buffer.py deleted file mode 100755 index ccb8302..0000000 --- a/pexpect/tests/platform_tests/test_middle_buffer.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python2 -import expyct -import time - -e = expyct.expyct ('/bin/sh -i') -e.timeout=60 -e.expect(['#', '\$']) -e.send ('ls -la /\n') - -i = e.expect (['foo','(d[aeiou]v)']) -print '\nRead before match>%s<' % e.before -print 'Matched:>%s<' % e.matched -print 'index:', i - -i = e.expect(['#', '\$']) -print '\nRead before match>%s<' % e.before -print 'Matched:>%s<' % e.matched -print 'index:', i -e.send('exit\n') -print 'Sent exit' -time.sleep(2) -print 'isAlive:', e.isAlive() - -# This should test timeout... -i = e.expect ('#####') -print '\nRead before match>%s<' % e.before -print 'Matched:>%s<' % e.matched -print 'index:', i - - diff --git a/pexpect/tests/platform_tests/test_read.py b/pexpect/tests/platform_tests/test_read.py deleted file mode 100755 index 1e16ed4..0000000 --- a/pexpect/tests/platform_tests/test_read.py +++ /dev/null @@ -1,35 +0,0 @@ -import os, sys - -filename = os.tmpnam() -print 'filename:', filename - -fd_out = os.open(filename, os.O_CREAT | os.O_WRONLY) -print 'fd_out:', fd_out -os.write (fd_out, 'This is a test.\n') -os.close(fd_out) -print -print 'testing read on good fd...' -fd_in = os.open (filename, os.O_RDONLY) -print 'fd_in:', fd_in -while 1: - data_in = os.read(fd_in, 1) - print 'data_in:', data_in - if data_in == '': - print 'data_in was empty' - break #sys.exit(1) -os.close(fd_in) -print -print -print 'testing read on closed fd...' -fd_in = os.open ('test_read.py', os.O_RDONLY) -print 'fd_in:', fd_in -while 1: - data_in = os.read(fd_in, 1) - print 'data_in:', data_in - if data_in == '': - print 'data_in was empty' - break -os.close(fd_in) -d = os.read(fd_in, 1) # fd_in should be closed now... -if s == '': - print 'd is empty. good.' diff --git a/pexpect/tests/platform_tests/test_signals.py b/pexpect/tests/platform_tests/test_signals.py deleted file mode 100755 index cd1a6da..0000000 --- a/pexpect/tests/platform_tests/test_signals.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python -import signal, os, time, errno, pty, sys -GLOBAL_SIGCHLD_RECEIVED = 0 - -def signal_handler (signum, frame): - print '<HANDLER>' - global GLOBAL_SIGCHLD_RECEIVED - status = os.waitpid (-1, os.WNOHANG) - print 'WIFEXITED(status):', os.WIFEXITED(status) - print 'WEXITSTATUS(status):', os.WEXITSTATUS(status) - GLOBAL_SIGCHLD_RECEIVED = 1 - -def main (): -# sig_test ('SIG_IGN', 'ptyfork', 'yes') - sig_test ('handler', 'ptyfork', 'yes') -# sig_test ('SIG_IGN', 'ptyfork', 'no') -# sig_test ('handler', 'ptyfork', 'no') -# sig_test ('SIG_IGN', 'osfork', 'yes') -# sig_test ('handler', 'osfork', 'yes') -# sig_test ('SIG_IGN', 'osfork', 'no') -# sig_test ('handler', 'osfork', 'no') - -def sig_test (sig_handler_type, fork_type, child_output): - print 'Testing with:' - print '\tsig_handler_type:', sig_handler_type - print '\tfork_type:', fork_type - print '\tchild_output:', child_output - - if sig_handler_type == 'SIG_IGN': - signal.signal (signal.SIGCHLD, signal.SIG_IGN) - else: - signal.signal (signal.SIGCHLD, signal_handler) - pid = -1 - fd = -1 - if fork_type == 'ptyfork': - pid, fd = pty.fork() - else: - pid = os.fork() - - if pid == 0: - if child_output == 'yes': - os.write (sys.stdout.fileno(), 'This is a test.\nThis is a test.') - time.sleep(10000) - - #print 'Sending SIGKILL to child pid:', pid - time.sleep(2) - os.kill (pid, signal.SIGKILL) - - #print 'Entering to sleep...' - try: - time.sleep(2) - except: - pass - try: - os.kill(pid, 0) - print '\tChild is alive. This is ambiguous because it may be a Zombie.' - except OSError, e: - print '\tChild appears to be dead.' -# print str(e) - print - -if __name__ == '__main__': - main () diff --git a/pexpect/tests/qa.py b/pexpect/tests/qa.py deleted file mode 100755 index eb11946..0000000 --- a/pexpect/tests/qa.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import commands -import signal - -signal.signal(signal.SIGCHLD, signal.SIG_IGN) -print commands.getoutput('/bin/ls -l') - diff --git a/pexpect/tests/sigwinch_report.py b/pexpect/tests/sigwinch_report.py deleted file mode 100755 index 26030cb..0000000 --- a/pexpect/tests/sigwinch_report.py +++ /dev/null @@ -1,46 +0,0 @@ -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import signal, time, struct, fcntl, termios, os, sys - -def getwinsize(): - '''This returns the window size of the child tty. - The return value is a tuple of (rows, cols). - ''' - if 'TIOCGWINSZ' in dir(termios): - TIOCGWINSZ = termios.TIOCGWINSZ - else: - TIOCGWINSZ = 1074295912L # Assume - s = struct.pack('HHHH', 0, 0, 0, 0) - x = fcntl.ioctl(sys.stdout.fileno(), TIOCGWINSZ, s) - return struct.unpack('HHHH', x)[0:2] - -def handler(signum, frame): - print 'signal' - sys.stdout.flush() - print 'SIGWINCH:', getwinsize () - sys.stdout.flush() - -print "setting handler for SIGWINCH" -signal.signal(signal.SIGWINCH, handler) - -while 1: - sys.stdout.flush() - time.sleep(1) - diff --git a/pexpect/tests/swapcase_echo.py b/pexpect/tests/swapcase_echo.py deleted file mode 100755 index 344cfaf..0000000 --- a/pexpect/tests/swapcase_echo.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import sys, time -while True: - x = raw_input () - time.sleep(1) # without this delay the test would fail about 75% of the time. Why? - print x.swapcase() - sys.stdout.flush() diff --git a/pexpect/tests/test_ansi.py b/pexpect/tests/test_ansi.py deleted file mode 100755 index 4ac7b9a..0000000 --- a/pexpect/tests/test_ansi.py +++ /dev/null @@ -1,133 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import ANSI -import unittest -import PexpectTestCase - -write_target = 'I\'ve got a ferret sticking up my nose. \n' +\ -'(He\'s got a ferret sticking up his nose.) \n' +\ -'How it got there I can\'t tell \n' +\ -'But now it\'s there it hurts like hell \n' +\ -'And what is more it radically affects my sense of smell. \n' +\ -'(His sense of smell.) ' - -write_text = 'I\'ve got a ferret sticking up my nose.\n' + \ -'(He\'s got a ferret sticking up his nose.)\n' + \ -'How it got there I can\'t tell\n' + \ -'But now it\'s there it hurts like hell\n' + \ -'And what is more it radically affects my sense of smell.\n' + \ -'(His sense of smell.)\n' + \ -'I can see a bare-bottomed mandril.\n' + \ -'(Slyly eyeing his other nostril.)\n' + \ -'If it jumps inside there too I really don\'t know what to do\n' + \ -'I\'ll be the proud posessor of a kind of nasal zoo.\n' + \ -'(A nasal zoo.)\n' + \ -'I\'ve got a ferret sticking up my nose.\n' + \ -'(And what is worst of all it constantly explodes.)\n' + \ -'"Ferrets don\'t explode," you say\n' + \ -'But it happened nine times yesterday\n' + \ -'And I should know for each time I was standing in the way.\n' + \ -'I\'ve got a ferret sticking up my nose.\n' + \ -'(He\'s got a ferret sticking up his nose.)\n' + \ -'How it got there I can\'t tell\n' + \ -'But now it\'s there it hurts like hell\n' + \ -'And what is more it radically affects my sense of smell.\n' + \ -'(His sense of smell.)' - -tetris_target=' XX XXXX XX \n' +\ -' XXXXXX XXXXXXXX XX \n' +\ -' XXXXXX XXXXXXXX XX \n' +\ -' XX XX XX XXXX XX \n' +\ -' XXXXXX XXXX XXXX XX \n' +\ -' XXXXXXXXXX XXXX XX \n' +\ -' XX XXXXXX XX XX \n' +\ -' XXXXXX XX XX \n' +\ -' XXXX XXXXXX XX XX \n' +\ -' XXXXXX XXXX XX XX \n' +\ -' XX XX XXXX XX XX \n' +\ -' XX XX XX XX XX \n' +\ -' XX XX XXXX XXXX XX \n' +\ -' XXXXXXXX XXXX XXXX XX \n' +\ -' XXXXXXXXXXXXXX XXXXXXXX \n' +\ -' XX XXXXXXXX XX XX \n' +\ -' XXXXXXXXXXXXXX XX XX \n' +\ -' XX XXXX XXXXXX XX \n' +\ -' XXXXXX XXXXXXXX \n' +\ -' XXXXXXXXXX XX XX \n' +\ -' XXXXXXXXXXXXXXXXXXXXXXXX \n' +\ -' \n' +\ -' J->LEFT K->ROTATE L->RIGHT SPACE->DROP P->PAUSE Q->QUIT \n' +\ -' ' - -torture_target='+--------------------------------------------------------------------------------+\n' +\ -'|a`opqrs` This is the `srqpo`a |\n' +\ -'|VT100 series Torture Test Demonstration. |\n' +\ -'|VT100 series Torture Test Demonstration. |\n' +\ -'|This is a normal line __________________________________________________y_ |\n' +\ -'|This is a bold line (normal unless the Advanced Video Option is installed) |\n' +\ -'|This line is underlined _ " " " " " " _y_ |\n' +\ -'|This is a blinking line _ " " " " " " _y_ |\n' +\ -'|This is inverse video _ (underlined if no AVO and cursor is underline) _y_ |\n' +\ -'|Normal gjpqy Underline Blink Underline+Blink gjpqy |\n' +\ -'|Bold gjpqy Underline Blink Underline+Blink gjpqy |\n' +\ -'|Inverse Underline Blink Underline+Blink |\n' +\ -'|Bold+Inverse Underline Blink Underline+Blink |\n' +\ -'|This is double width |\n' +\ -'|This is double height |\n' +\ -'|This is double height |\n' +\ -'|_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ioy |\n' +\ -'|_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ioy |\n' +\ -'|_ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ioy |\n' +\ -'|`abcdefghijklmnopqrstuvwxyz{|}~ lqwqk |\n' +\ -'|`abcdefghijklmnopqrstuvwxyz{|}~ tqnqu |\n' +\ -'|`abcdefghijklmnopqrstuvwxyz{|}~ tqnqu |\n' +\ -'|`abcdefghijklmnopqrstuvwxyz{|}~ mqvqj |\n' +\ -'| This test created by Joe Smith, 8-May-85 |\n' +\ -'| |\n' +\ -'+--------------------------------------------------------------------------------+\n' - -class ansiTestCase (PexpectTestCase.PexpectTestCase): - def test_write (self): - s = ANSI.ANSI (6,65) - s.fill('.') - s.cursor_home() - for c in write_text: - s.write (c) - assert str(s) == write_target - def test_torturet (self): - s = ANSI.ANSI (24,80) - sample_text = open ('torturet.vt').read() - for c in sample_text: - s.process (c) - assert s.pretty() == torture_target, 'processed: \n' + s.pretty() + '\nexpected:\n' + torture_target - def test_tetris (self): - s = ANSI.ANSI (24,80) - tetris_text = open ('tetris.data').read() - for c in tetris_text: - s.process (c) - assert str(s) == tetris_target - -if __name__ == '__main__': - unittest.main() - -suite = unittest.makeSuite(ansiTestCase,'test') - diff --git a/pexpect/tests/test_command_list_split.py b/pexpect/tests/test_command_list_split.py deleted file mode 100755 index 2213b45..0000000 --- a/pexpect/tests/test_command_list_split.py +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import pexpect -import unittest -import PexpectTestCase -class SplitCommandLineTestCase(PexpectTestCase.PexpectTestCase): - def testSplitSizes(self): - assert len(pexpect.split_command_line(r'')) == 0 - assert len(pexpect.split_command_line(r'one')) == 1 - assert len(pexpect.split_command_line(r'one two')) == 2 - assert len(pexpect.split_command_line(r'one two')) == 2 - assert len(pexpect.split_command_line(r'one two')) == 2 - assert len(pexpect.split_command_line(r'one\ one')) == 1 - assert len(pexpect.split_command_line('\'one one\'')) == 1 - assert len(pexpect.split_command_line(r'one\"one')) == 1 - assert len(pexpect.split_command_line(r'This\' is a\'\ test')) == 3 - -if __name__ == '__main__': - unittest.main() - -suite = unittest.makeSuite(SplitCommandLineTestCase,'test') diff --git a/pexpect/tests/test_constructor.py b/pexpect/tests/test_constructor.py deleted file mode 100755 index 8a98c28..0000000 --- a/pexpect/tests/test_constructor.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import pexpect -import unittest -import time -import PexpectTestCase - -class TestCaseConstructor(PexpectTestCase.PexpectTestCase): - def test_constructor (self): - '''This tests that the constructor will work and give - the same results for different styles of invoking __init__(). - This assumes that the root directory / is static during the test. - ''' - p1 = pexpect.spawn('/bin/ls -l /bin') - p2 = pexpect.spawn('/bin/ls' ,['-l', '/bin']) - p1.expect (pexpect.EOF) - p2.expect (pexpect.EOF) - assert (p1.before == p2.before) - - def test_named_parameters (self): - '''This tests that named parameters work. - ''' - p = pexpect.spawn ('/bin/ls',timeout=10) - p = pexpect.spawn (timeout=10, command='/bin/ls') - p = pexpect.spawn (args=[], command='/bin/ls') - -if __name__ == '__main__': - unittest.main() - -suite = unittest.makeSuite(TestCaseConstructor,'test') - diff --git a/pexpect/tests/test_ctrl_chars.py b/pexpect/tests/test_ctrl_chars.py deleted file mode 100755 index c679609..0000000 --- a/pexpect/tests/test_ctrl_chars.py +++ /dev/null @@ -1,109 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import pexpect -import unittest -import PexpectTestCase -import time -import os - -class TestCtrlChars(PexpectTestCase.PexpectTestCase): - - def test_control_chars (self): - - '''FIXME: Python unicode was too hard to figure out, so - this tests only the true ASCII characters. This is lame - and should be fixed. I'm leaving this script here as a - placeholder so that it will remind me to fix this one day. - This is what it used to do: - This tests that we can send all 256 8-bit ASCII characters - to a child process.''' - - # FIXME: Getting this to support Python's Unicode was - # too hard, so I disabled this. I should fix this one day. - return 0 - child = pexpect.spawn('python getch.py') - try: - for i in range(256): -# child.send(unicode('%d'%i, encoding='utf-8')) - child.send(chr(i)) - child.expect ('%d\r\n' % i) - except Exception, e: - msg = "Did not echo character value: " + str(i) + "\n" - msg = msg + str(e) - self.fail(msg) - - def test_sendintr (self): - try: - child = pexpect.spawn('python getch.py') - child.sendintr() - child.expect ('3\r\n') - except Exception, e: - msg = "Did not echo character value: 3\n" - msg = msg + str(e) - self.fail(msg) - - def test_bad_sendcontrol_chars (self): - - '''This tests that sendcontrol will return 0 for an unknown char. ''' - - child = pexpect.spawn('python getch.py') - retval = child.sendcontrol('1') - assert retval == 0, "sendcontrol() should have returned 0 because there is no such thing as ctrl-1." - - def test_sendcontrol(self): - - '''This tests that we can send all special control codes by name. - ''' - - child = pexpect.spawn('python getch.py') - #child.delaybeforesend = 0.1 - for i in 'abcdefghijklmnopqrstuvwxyz': - child.sendcontrol(i) - child.expect ('[0-9]+\r\n') - #print child.after - - child.sendcontrol('@') - child.expect ('0\r\n') - #print child.after - child.sendcontrol('[') - child.expect ('27\r\n') - #print child.after - child.sendcontrol('\\') - child.expect ('28\r\n') - #print child.after - child.sendcontrol(']') - child.expect ('29\r\n') - #print child.after - child.sendcontrol('^') - child.expect ('30\r\n') - #print child.after - child.sendcontrol('_') - child.expect ('31\r\n') - #print child.after - child.sendcontrol('?') - child.expect ('127\r\n') - #print child.after - -if __name__ == '__main__': - unittest.main() - -suite = unittest.makeSuite(TestCtrlChars,'test') - diff --git a/pexpect/tests/test_destructor.py b/pexpect/tests/test_destructor.py deleted file mode 100755 index d6b176c..0000000 --- a/pexpect/tests/test_destructor.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import pexpect -import unittest -import PexpectTestCase -import gc -import time - -class TestCaseDestructor(PexpectTestCase.PexpectTestCase): - def test_destructor (self): - p1 = pexpect.spawn('%s hello_world.py' % self.PYTHONBIN) - p2 = pexpect.spawn('%s hello_world.py' % self.PYTHONBIN) - p3 = pexpect.spawn('%s hello_world.py' % self.PYTHONBIN) - p4 = pexpect.spawn('%s hello_world.py' % self.PYTHONBIN) - fd_t1 = (p1.child_fd,p2.child_fd,p3.child_fd,p4.child_fd) - p1.expect(pexpect.EOF) - p2.expect(pexpect.EOF) - p3.expect(pexpect.EOF) - p4.expect(pexpect.EOF) - p1.kill(9) - p2.kill(9) - p3.kill(9) - p4.kill(9) - p1 = None - p2 = None - p3 = None - p4 = None - gc.collect() - time.sleep(3) # Some platforms are slow at gc... Solaris! - - p1 = pexpect.spawn('%s hello_world.py' % self.PYTHONBIN) - p2 = pexpect.spawn('%s hello_world.py' % self.PYTHONBIN) - p3 = pexpect.spawn('%s hello_world.py' % self.PYTHONBIN) - p4 = pexpect.spawn('%s hello_world.py' % self.PYTHONBIN) - fd_t2 = (p1.child_fd,p2.child_fd,p3.child_fd,p4.child_fd) - p1.kill(9) - p2.kill(9) - p3.kill(9) - p4.kill(9) - del (p1) - del (p2) - del (p3) - del (p4) - gc.collect() - time.sleep(3) - - p1 = pexpect.spawn('%s hello_world.py' % self.PYTHONBIN) - p2 = pexpect.spawn('%s hello_world.py' % self.PYTHONBIN) - p3 = pexpect.spawn('%s hello_world.py' % self.PYTHONBIN) - p4 = pexpect.spawn('%s hello_world.py' % self.PYTHONBIN) - fd_t3 = (p1.child_fd,p2.child_fd,p3.child_fd,p4.child_fd) - - assert (fd_t1 == fd_t2 == fd_t3), "pty file descriptors not properly garbage collected (fd_t1,fd_t2,fd_t3)=(%s,%s,%s)" % (str(fd_t1),str(fd_t2),str(fd_t3)) - - -if __name__ == '__main__': - unittest.main() - -suite = unittest.makeSuite(TestCaseDestructor,'test') - diff --git a/pexpect/tests/test_dotall.py b/pexpect/tests/test_dotall.py deleted file mode 100755 index 46577da..0000000 --- a/pexpect/tests/test_dotall.py +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import pexpect -import unittest -import os -import re -import PexpectTestCase - -testdata = 'BEGIN\nHello world\nEND' -class TestCaseDotall(PexpectTestCase.PexpectTestCase): - def test_dotall (self): - p = pexpect.spawn('echo "%s"' % testdata) - i = p.expect (['BEGIN(.*)END', pexpect.EOF]) - assert i==0, 'DOTALL does not seem to be working.' - - def test_precompiled (self): - p = pexpect.spawn('echo "%s"' % testdata) - pat = re.compile('BEGIN(.*)END') # This overrides the default DOTALL. - i = p.expect ([pat, pexpect.EOF]) - assert i==1, 'Precompiled pattern to override DOTALL does not seem to be working.' - -if __name__ == '__main__': - unittest.main() - -suite = unittest.makeSuite(TestCaseDotall,'test') - diff --git a/pexpect/tests/test_expect.py b/pexpect/tests/test_expect.py deleted file mode 100755 index 7075aa0..0000000 --- a/pexpect/tests/test_expect.py +++ /dev/null @@ -1,424 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import pexpect -import unittest -import commands -import sys, time -import PexpectTestCase -#import pdb - -# Many of these test cases blindly assume that sequential directory -# listings of the /bin directory will yield the same results. -# This may not be true, but seems adequate for testing now. -# I should fix this at some point. - -FILTER=''.join([(len(repr(chr(x)))==3) and chr(x) or '.' for x in range(256)]) -def hex_dump(src, length=16): - result=[] - for i in xrange(0, len(src), length): - s = src[i:i+length] - hexa = ' '.join(["%02X"%ord(x) for x in s]) - printable = s.translate(FILTER) - result.append("%04X %-*s %s\n" % (i, length*3, hexa, printable)) - return ''.join(result) - -class ExpectTestCase (PexpectTestCase.PexpectTestCase): - - def test_expect_basic (self): - p = pexpect.spawn('cat') - p.sendline ('Hello') - p.sendline ('there') - p.sendline ('Mr. Python') - p.expect ('Hello') - p.expect ('there') - p.expect ('Mr. Python') - p.sendeof () - p.expect (pexpect.EOF) - - def test_expect_exact_basic (self): - p = pexpect.spawn('cat') - p.sendline ('Hello') - p.sendline ('there') - p.sendline ('Mr. Python') - p.expect_exact ('Hello') - p.expect_exact ('there') - p.expect_exact ('Mr. Python') - p.sendeof () - p.expect_exact (pexpect.EOF) - - def test_expect_ignore_case(self): - '''This test that the ignorecase flag will match patterns - even if case is different using the regex (?i) directive. - ''' - p = pexpect.spawn('cat') - p.sendline ('HELLO') - p.sendline ('there') - p.expect ('(?i)hello') - p.expect ('(?i)THERE') - p.sendeof () - p.expect (pexpect.EOF) - - def test_expect_ignore_case_flag(self): - '''This test that the ignorecase flag will match patterns - even if case is different using the ignorecase flag. - ''' - p = pexpect.spawn('cat') - p.ignorecase = True - p.sendline ('HELLO') - p.sendline ('there') - p.expect ('hello') - p.expect ('THERE') - p.sendeof () - p.expect (pexpect.EOF) - - def test_expect_order (self): - '''This tests that patterns are matched in the same order as given in the pattern_list. - - (Or does it? Doesn't it also pass if expect() always chooses - (one of the) the leftmost matches in the input? -- grahn) - ''' - p = pexpect.spawn('cat') - self._expect_order(p) - - def test_expect_order_exact (self): - '''Like test_expect_order(), but using expect_exact(). - ''' - p = pexpect.spawn('cat') - p.expect = p.expect_exact - self._expect_order(p) - - def _expect_order (self, p): - p.sendline ('1234') - p.sendline ('abcd') - p.sendline ('wxyz') - p.sendline ('7890') - p.sendeof () - index = p.expect (['1234','abcd','wxyz',pexpect.EOF,'7890']) - assert index == 0, "index="+str(index) - index = p.expect (['1234','abcd','wxyz',pexpect.EOF,'7890']) - assert index == 0, "index="+str(index) - index = p.expect ([pexpect.EOF,pexpect.TIMEOUT,'wxyz','abcd','1234']) - assert index == 3, "index="+str(index) - index = p.expect (['54321',pexpect.TIMEOUT,'1234','abcd','wxyz',pexpect.EOF], timeout=5) - assert index == 3, "index="+str(index) - index = p.expect (['54321',pexpect.TIMEOUT,'1234','abcd','wxyz',pexpect.EOF], timeout=5) - assert index == 4, "index="+str(index) - index = p.expect (['54321',pexpect.TIMEOUT,'1234','abcd','wxyz',pexpect.EOF], timeout=5) - assert index == 4, "index="+str(index) - index = p.expect ([pexpect.EOF,'abcd','wxyz','7890']) - assert index == 3, "index="+str(index) - index = p.expect ([pexpect.EOF,'abcd','wxyz','7890']) - assert index == 3, "index="+str(index) - - def test_waitnoecho (self): - - ''' This tests that we can wait on a child process to set echo mode. - For example, this tests that we could wait for SSH to set ECHO False - when asking of a password. This makes use of an external script - echo_wait.py. ''' - - p1 = pexpect.spawn('%s echo_wait.py' % self.PYTHONBIN) - start = time.time() - p1.waitnoecho(timeout=10) - end_time = time.time() - start - assert end_time < 10 and end_time > 2, "waitnoecho did not set ECHO off in the expected window of time." - - # test that we actually timeout and return False if ECHO is never set off. - p1 = pexpect.spawn('cat') - start = time.time() - retval = p1.waitnoecho(timeout=4) - end_time = time.time() - start - assert end_time > 3, "waitnoecho should have waited longer than 2 seconds. retval should be False, retval=%d"%retval - assert retval==False, "retval should be False, retval=%d"%retval - - # This one is mainly here to test default timeout for code coverage. - p1 = pexpect.spawn('%s echo_wait.py' % self.PYTHONBIN) - start = time.time() - p1.waitnoecho() - end_time = time.time() - start - assert end_time < 10, "waitnoecho did not set ECHO off in the expected window of time." - - def test_expect_echo (self): - '''This tests that echo can be turned on and off. - ''' - p = pexpect.spawn('cat', timeout=10) - self._expect_echo(p) - - def test_expect_echo_exact (self): - '''Like test_expect_echo(), but using expect_exact(). - ''' - p = pexpect.spawn('cat', timeout=10) - p.expect = p.expect_exact - self._expect_echo(p) - - def _expect_echo (self, p): - p.sendline ('1234') # Should see this twice (once from tty echo and again from cat). - index = p.expect (['1234','abcd','wxyz',pexpect.EOF,pexpect.TIMEOUT]) - assert index == 0, "index="+str(index)+"\n"+p.before - index = p.expect (['1234','abcd','wxyz',pexpect.EOF]) - assert index == 0, "index="+str(index) - p.setecho(0) # Turn off tty echo - p.sendline ('abcd') # Now, should only see this once. - p.sendline ('wxyz') # Should also be only once. - index = p.expect ([pexpect.EOF,pexpect.TIMEOUT,'abcd','wxyz','1234']) - assert index == 2, "index="+str(index) - index = p.expect ([pexpect.EOF,'abcd','wxyz','7890']) - assert index == 2, "index="+str(index) - p.setecho(1) # Turn on tty echo - p.sendline ('7890') # Should see this twice. - index = p.expect ([pexpect.EOF,'abcd','wxyz','7890']) - assert index == 3, "index="+str(index) - index = p.expect ([pexpect.EOF,'abcd','wxyz','7890']) - assert index == 3, "index="+str(index) - p.sendeof() - - def test_expect_index (self): - '''This tests that mixed list of regex strings, TIMEOUT, and EOF all - return the correct index when matched. - ''' - #pdb.set_trace() - p = pexpect.spawn('cat') - self._expect_index(p) - - def test_expect_index_exact (self): - '''Like test_expect_index(), but using expect_exact(). - ''' - p = pexpect.spawn('cat') - p.expect = p.expect_exact - self._expect_index(p) - - def _expect_index (self, p): - p.setecho(0) - p.sendline ('1234') - index = p.expect (['abcd','wxyz','1234',pexpect.EOF]) - assert index == 2, "index="+str(index) - p.sendline ('abcd') - index = p.expect ([pexpect.TIMEOUT,'abcd','wxyz','1234',pexpect.EOF]) - assert index == 1, "index="+str(index) - p.sendline ('wxyz') - index = p.expect (['54321',pexpect.TIMEOUT,'abcd','wxyz','1234',pexpect.EOF], timeout=5) - assert index == 3, "index="+str(index) # Expect 'wxyz' - p.sendline ('$*!@?') - index = p.expect (['54321',pexpect.TIMEOUT,'abcd','wxyz','1234',pexpect.EOF], timeout=5) - assert index == 1, "index="+str(index) # Expect TIMEOUT - p.sendeof () - index = p.expect (['54321',pexpect.TIMEOUT,'abcd','wxyz','1234',pexpect.EOF], timeout=5) - assert index == 5, "index="+str(index) # Expect EOF - - def test_expect (self): - the_old_way = commands.getoutput('ls -l /bin') - p = pexpect.spawn('ls -l /bin') - the_new_way = '' - while 1: - i = p.expect (['\n', pexpect.EOF]) - the_new_way = the_new_way + p.before - if i == 1: - break - the_new_way = the_new_way[:-1] - the_new_way = the_new_way.replace('\r','\n') - # For some reason I get an extra newline under OS X evey once in a while. - # I found it by looking through the hex_dump(). - assert the_old_way == the_new_way, hex_dump(the_new_way) + "\n" + hex_dump(the_old_way) - - def test_expect_exact (self): - the_old_way = commands.getoutput('ls -l /bin') - p = pexpect.spawn('ls -l /bin') - the_new_way = '' - while 1: - i = p.expect_exact (['\n', pexpect.EOF]) - the_new_way = the_new_way + p.before - if i == 1: - break - the_new_way = the_new_way[:-1] - the_new_way = the_new_way.replace('\r','\n') - assert the_old_way == the_new_way, repr(the_old_way) + '\n' + repr(the_new_way) - p = pexpect.spawn('echo hello.?world') - i = p.expect_exact('.?') - assert p.before == 'hello' and p.after == '.?' - - def test_expect_eof (self): - the_old_way = commands.getoutput('/bin/ls -l /bin') - p = pexpect.spawn('/bin/ls -l /bin') - p.expect(pexpect.EOF) # This basically tells it to read everything. Same as pexpect.run() function. - the_new_way = p.before - the_new_way = the_new_way.replace('\r','') # Remember, pty line endings are '\r\n'. - the_new_way = the_new_way[:-1] - assert the_old_way == the_new_way - - def test_expect_timeout (self): - p = pexpect.spawn('ed', timeout=10) - i = p.expect(pexpect.TIMEOUT) # This tells it to wait for timeout. - assert p.after == pexpect.TIMEOUT - - def test_unexpected_eof (self): - p = pexpect.spawn('ls -l /bin') - try: - p.expect('_Z_XY_XZ') # Probably never see this in ls output. - except pexpect.EOF, e: - pass - else: - self.fail ('Expected an EOF exception.') - - def _before_after(self, p): - p.timeout = 5 - - p.expect('>>> ') - self.assertEqual(p.after, '>>> ') - self.assert_(p.before.startswith('Python ')) - - p.sendline('range(4*3)') - - p.expect('5') - self.assertEqual(p.after, '5') - self.assert_(p.before.startswith('range(4*3)')) - - p.expect('>>> ') - self.assertEqual(p.after, '>>> ') - self.assert_(p.before.startswith(', 6, 7, 8')) - - def test_before_after(self): - '''This tests expect() for some simple before/after things. - ''' - p = pexpect.spawn(self.PYTHONBIN) - self._before_after(p) - - def test_before_after_exact(self): - '''This tests some simple before/after things, for - expect_exact(). (Grahn broke it at one point.) - ''' - p = pexpect.spawn(self.PYTHONBIN) - # mangle the spawn so we test expect_exact() instead - p.expect = p.expect_exact - self._before_after(p) - - def _ordering(self, p): - p.timeout = 5 - p.expect('>>> ') - - p.sendline('range(4*3)') - self.assertEqual(p.expect(['5,', '5,']), 0) - p.expect('>>> ') - - p.sendline('range(4*3)') - self.assertEqual(p.expect(['7,', '5,']), 1) - p.expect('>>> ') - - p.sendline('range(4*3)') - self.assertEqual(p.expect(['5,', '7,']), 0) - p.expect('>>> ') - - p.sendline('range(4*5)') - self.assertEqual(p.expect(['2,', '12,']), 0) - p.expect('>>> ') - - p.sendline('range(4*5)') - self.assertEqual(p.expect(['12,', '2,']), 1) - - def test_ordering(self): - '''This tests expect() for which pattern is returned - when many may eventually match. I (Grahn) am a bit - confused about what should happen, but this test passes - with pexpect 2.1. - ''' - p = pexpect.spawn(self.PYTHONBIN) - self._ordering(p) - - def test_ordering_exact(self): - '''This tests expect_exact() for which pattern is returned - when many may eventually match. I (Grahn) am a bit - confused about what should happen, but this test passes - for the expect() method with pexpect 2.1. - ''' - p = pexpect.spawn(self.PYTHONBIN) - # mangle the spawn so we test expect_exact() instead - p.expect = p.expect_exact - self._ordering(p) - - def _greed(self, p): - p.timeout = 5 - p.expect('>>> ') - p.sendline('import time') - p.expect('>>> ') - # the newline and sleep will (I hope) guarantee that - # pexpect is fed two distinct batches of data, - # "foo\r\n" + "bar\r\n". - foo_then_bar = 'print "f"+"o"+"o" ; time.sleep(3); print "b"+"a"+"r"' - - p.sendline(foo_then_bar) - self.assertEqual(p.expect(['foo\r\nbar']), 0) - p.expect('>>> ') - - p.sendline(foo_then_bar) - self.assertEqual(p.expect(['\r\nbar']), 0) - p.expect('>>> ') - - p.sendline(foo_then_bar) - self.assertEqual(p.expect(['foo\r\nbar', 'foo', 'bar']), 1) - p.expect('>>> ') - - p.sendline(foo_then_bar) - self.assertEqual(p.expect(['foo', 'foo\r\nbar', 'foo', 'bar']), 0) - p.expect('>>> ') - - p.sendline(foo_then_bar) - self.assertEqual(p.expect(['bar', 'foo\r\nbar']), 1) - p.expect('>>> ') - - # If the expect works as if we rematch for every new character, - # 'o\r\nb' should win over 'oo\r\nba'. The latter is longer and - # matches earlier in the input, but isn't satisfied until the 'a' - # arrives. - # However, pexpect doesn't do that (version 2.1 didn't). - p.sendline(foo_then_bar) - self.assertEqual(p.expect(['oo\r\nba', 'o\r\nb']), 0) - p.expect('>>> ') - - # distinct patterns, but both suddenly match when the 'r' arrives. - p.sendline(foo_then_bar) - self.assertEqual(p.expect(['foo\r\nbar', 'ar']), 0) - p.expect('>>> ') - - p.sendline(foo_then_bar) - self.assertEqual(p.expect(['ar', 'foo\r\nbar']), 1) - p.expect('>>> ') - - def test_greed(self): - p = pexpect.spawn(self.PYTHONBIN) - self._greed(p) - - def test_greed_exact(self): - p = pexpect.spawn(self.PYTHONBIN) - # mangle the spawn so we test expect_exact() instead - p.expect = p.expect_exact - self._greed(p) - -if __name__ == '__main__': - unittest.main() - -suite = unittest.makeSuite(ExpectTestCase,'test') - -#fout = open('delete_me_1','wb') -#fout.write(the_old_way) -#fout.close -#fout = open('delete_me_2', 'wb') -#fout.write(the_new_way) -#fout.close - diff --git a/pexpect/tests/test_filedescriptor.py b/pexpect/tests/test_filedescriptor.py deleted file mode 100755 index 9eb553b..0000000 --- a/pexpect/tests/test_filedescriptor.py +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import fdpexpect, pexpect -import unittest -import PexpectTestCase -import sys -import os - -class ExpectTestCase(PexpectTestCase.PexpectTestCase): - def setUp(self): - print self.id() - PexpectTestCase.PexpectTestCase.setUp(self) - - def test_fd (self): - fd = os.open ('TESTDATA.txt', os.O_RDONLY) - s = fdpexpect.fdspawn (fd) - s.expect ('This is the end of test data:') - s.expect (pexpect.EOF) - assert s.before == ' END\n' - - def test_maxread (self): - fd = os.open ('TESTDATA.txt', os.O_RDONLY) - s = fdpexpect.fdspawn (fd) - s.maxread = 100 - s.expect('2') - s.expect ('This is the end of test data:') - s.expect (pexpect.EOF) - assert s.before == ' END\n' - - def test_fd_isalive (self): - fd = os.open ('TESTDATA.txt', os.O_RDONLY) - s = fdpexpect.fdspawn (fd) - assert s.isalive() - os.close (fd) - assert not s.isalive(), "Should not be alive after close()" - - def test_fd_isatty (self): - fd = os.open ('TESTDATA.txt', os.O_RDONLY) - s = fdpexpect.fdspawn (fd) - assert not s.isatty() - #os.close(fd) - s.close() - -### def test_close_does_not_close_fd (self): -### '''Calling close() on a fdpexpect.fdspawn object should not -### close the underlying file descriptor. -### ''' -### fd = os.open ('TESTDATA.txt', os.O_RDONLY) -### s = fdpexpect.fdspawn (fd) -### try: -### s.close() -### self.fail('Expected an Exception.') -### except pexpect.ExceptionPexpect, e: -### pass - -if __name__ == '__main__': - unittest.main() - -suite = unittest.makeSuite(ExpectTestCase, 'test') - -#fout = open('delete_me_1','wb') -#fout.write(the_old_way) -#fout.close -#fout = open('delete_me_2', 'wb') -#fout.write(the_new_way) -#fout.close diff --git a/pexpect/tests/test_interact.py b/pexpect/tests/test_interact.py deleted file mode 100755 index bbdb681..0000000 --- a/pexpect/tests/test_interact.py +++ /dev/null @@ -1,81 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import pexpect -import unittest -import commands -import sys, os, time, tty -import PexpectTestCase -import thread -import threading - -def start_interact (p): - p.interact() - -class InteractTestCase (PexpectTestCase.PexpectTestCase): - - def test_interact_thread (self): - # I can't believe this actually works... - # Note that I had to add a delay in the swapcase_echo.py script. - # I'm not sure why this helped. - p = pexpect.spawn('%s swapcase_echo.py' % self.PYTHONBIN) - mode = tty.tcgetattr(p.STDIN_FILENO) - t = threading.Thread (target=start_interact, args=(p,)) - t.start() - #thread.start_new_thread (start_interact, (p,)) - time.sleep(1) - p.sendline ('Hello') - #time.sleep(1) - try: - p.expect ('hELLO', timeout=4) - except Exception, e: - p.close(force = False) - tty.tcsetattr(p.STDIN_FILENO, tty.TCSAFLUSH, mode) - print str(p) - raise e - p.close(force = True) - tty.tcsetattr(p.STDIN_FILENO, tty.TCSAFLUSH, mode) -# def test_interact_thread (self): -# # I can't believe this actually works... -# p = pexpect.spawn('%s swapcase_echo.py' % self.PYTHONBIN) -# mode = tty.tcgetattr(p.STDIN_FILENO) -# thread.start_new_thread (start_interact, (p,)) -# time.sleep(1) -# p.sendline ('Hello') -# time.sleep(2) -# p.close(force = False) -# tty.tcsetattr(p.STDIN_FILENO, tty.TCSAFLUSH, mode) - - def test_interact (self): - p = pexpect.spawn('%s interact.py' % self.PYTHONBIN) - p.sendline ('Hello') - p.sendline ('there') - p.sendline ('Mr. Python') - p.expect ('Hello') - p.expect ('there') - p.expect ('Mr. Python') - p.sendeof () - p.expect (pexpect.EOF) - -if __name__ == '__main__': - unittest.main() - -suite = unittest.makeSuite(InteractTestCase,'test') - diff --git a/pexpect/tests/test_isalive.py b/pexpect/tests/test_isalive.py deleted file mode 100755 index 4c7e85e..0000000 --- a/pexpect/tests/test_isalive.py +++ /dev/null @@ -1,105 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import pexpect -import unittest -import sys, os, time -import PexpectTestCase - -class IsAliveTestCase(PexpectTestCase.PexpectTestCase): - - def test_expect_wait (self): - '''This tests that calling wait on a finished process works as expected. - ''' - p = pexpect.spawn('sleep 3') - if not p.isalive(): - self.fail ('Child process is not alive. It should be.') - time.sleep(1) - p.wait() - if p.isalive(): - self.fail ('Child process is not dead. It should be.') - p = pexpect.spawn('sleep 3') - if not p.isalive(): - self.fail ('Child process is not alive. It should be.') - p.kill(9) - time.sleep(1) - try: - p.wait() - except pexpect.ExceptionPexpect, e: - pass - else: - self.fail ('Should have raised ExceptionPython because you can\'t call wait on a dead process.') - - def test_expect_isalive_dead_after_normal_termination (self): - p = pexpect.spawn('ls') - p.expect(pexpect.EOF) - time.sleep(1) # allow kernel status time to catch up with state. - if p.isalive(): - self.fail ('Child process is not dead. It should be.') - - def test_expect_isalive_dead_after_SIGINT (self): - p = pexpect.spawn('cat', timeout=5) - if not p.isalive(): - self.fail ('Child process is not alive. It should be.') - p.terminate() - # Solaris is kind of slow. - # Without this delay then p.expect(...) will not see - # that the process is dead and it will timeout. - time.sleep(1) - p.expect(pexpect.EOF) - if p.isalive(): - self.fail ('Child process is not dead. It should be.') - - def test_expect_isalive_dead_after_SIGKILL (self): - p = pexpect.spawn('cat', timeout=3) - if not p.isalive(): - self.fail ('Child process is not alive. It should be.') - p.kill(9) - # Solaris is kind of slow. - # Without this delay then p.expect(...) will not see - # that the process is dead and it will timeout. - time.sleep(1) - p.expect(pexpect.EOF) - if p.isalive(): - self.fail ('Child process is not dead. It should be.') - -### Some platforms allow this. Some reset status after call to waitpid. - def test_expect_isalive_consistent_multiple_calls (self): - - '''This tests that multiple calls to isalive() return same value. - ''' - - p = pexpect.spawn('cat') - if not p.isalive(): - self.fail ('Child process is not alive. It should be.') - if not p.isalive(): - self.fail ('Second call. Child process is not alive. It should be.') - p.kill(9) - p.expect(pexpect.EOF) - if p.isalive(): - self.fail ('Child process is not dead. It should be.') - if p.isalive(): - self.fail ('Second call. Child process is not dead. It should be.') - -if __name__ == '__main__': - unittest.main() - -suite = unittest.makeSuite(IsAliveTestCase, 'test') - diff --git a/pexpect/tests/test_log.py b/pexpect/tests/test_log.py deleted file mode 100755 index c3af9a7..0000000 --- a/pexpect/tests/test_log.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import pexpect -import unittest -import os -import tempfile -import PexpectTestCase - -class TestCaseLog(PexpectTestCase.PexpectTestCase): - - def test_log (self): - log_message = 'This is a test.' - filename = tempfile.mktemp() - mylog = open (filename, 'w') - p = pexpect.spawn('echo', [log_message]) - p.logfile = mylog - p.expect (pexpect.EOF) - p.logfile = None - mylog.close() - lf = open(filename).read() - lf = lf[:-2] - os.unlink (filename) - assert lf == log_message - - def test_log_logfile_read (self): - log_message = 'This is a test.' - filename = tempfile.mktemp() - mylog = open (filename, 'w') - p = pexpect.spawn('cat') - p.logfile_read = mylog - p.sendline(log_message) - p.sendeof() - p.expect (pexpect.EOF) - p.logfile = None - mylog.close() - lf = open(filename).read() - lf = lf[:-2] - os.unlink (filename) - lf = lf.replace(chr(4),'') - assert lf == 'This is a test.\r\nThis is a test.', "The read log file has bad data. Note logfile_read should only record what we read from child and nothing else.\n" + repr(lf) - - def test_log_logfile_send (self): - log_message = 'This is a test.' - filename = tempfile.mktemp() - mylog = open (filename, 'w') - p = pexpect.spawn('cat') - p.logfile_send = mylog - p.sendline(log_message) - p.sendeof() - p.expect (pexpect.EOF) - p.logfile = None - mylog.close() - lf = open(filename).read() - lf = lf[:-2] - os.unlink (filename) - assert lf == log_message, "The send log file has bad data. Note logfile_send should only record what we sent to child and nothing else." - - def test_log_send_and_received (self): - - '''The logfile should have the test message three time -- once for the - data we sent. Once for the data that cat echos back as characters are - typed. And once for the data that cat prints after we send a linefeed - (sent by sendline). ''' - - log_message = 'This is a test.' - filename = tempfile.mktemp() - mylog = open (filename, 'w') - p = pexpect.spawn('cat') - p.logfile = mylog - p.sendline(log_message) - p.sendeof() - p.expect (pexpect.EOF) - p.logfile = None - mylog.close() - lf = open(filename).read() - os.unlink (filename) - lf = lf.replace(chr(4),'') - assert lf == 'This is a test.\nThis is a test.\r\nThis is a test.\r\n', repr(lf) - -if __name__ == '__main__': - unittest.main() - -suite = unittest.makeSuite(TestCaseLog,'test') - diff --git a/pexpect/tests/test_misc.py b/pexpect/tests/test_misc.py deleted file mode 100755 index 61abfde..0000000 --- a/pexpect/tests/test_misc.py +++ /dev/null @@ -1,217 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import pexpect -import unittest -import PexpectTestCase -import time -import os -import re - -class TestCaseMisc(PexpectTestCase.PexpectTestCase): - - def test_isatty (self): - child = pexpect.spawn('cat') - assert child.isatty(), "Not returning True. Should always be True." - def test_read (self): - child = pexpect.spawn('cat') - child.sendline ("abc") - child.sendeof() - assert child.read(0) == '', "read(0) did not return ''" - assert child.read(1) == 'a', "read(1) did not return 'a'" - assert child.read(1) == 'b', "read(1) did not return 'b'" - assert child.read(1) == 'c', "read(1) did not return 'c'" - assert child.read(2) == '\r\n', "read(2) did not return '\\r\\n'" - assert child.read() == 'abc\r\n', "read() did not return 'abc\\r\\n'" - def test_readline (self): - '''See the note in test_readlines() for an explaination as to why - I allow line3 and line4 to return multiple patterns. - Basically, this is done to handle a valid condition on slow systems. - ''' - child = pexpect.spawn('cat') - child.sendline ("abc") - child.sendline ("123") - child.sendeof() - line1 = child.readline(0) - line2 = child.readline() - line3 = child.readline(2) - line4 = child.readline(1) - line5 = child.readline() - assert line1 == '', "readline(0) did not return ''. Returned: " + repr(line1) - assert line2 == 'abc\r\n', "readline() did not return 'abc\\r\\n'. Returned: " + repr(line2) - assert ( (line3 == 'abc\r\n' or line3 == '123\r\n'), - "readline(2) did not return 'abc\\r\\n'. Returned: " - + repr(line3) ) - assert ( (line4 == '123\r\n' or line4 == 'abc\r\n'), - "readline(1) did not return '123\\r\\n'. Returned: " - + repr(line4) ) - assert line5 == '123\r\n', "readline() did not return '123\\r\\n'. Returned: " + repr(line5) - def test_iter (self): - '''See the note in test_readlines() for an explaination as to why - I allow line3 and line4 to return multiple patterns. - Basically, this is done to handle a valid condition on slow systems. - ''' - child = pexpect.spawn('cat') - child.sendline ("abc") - child.sendline ("123") - child.sendeof() - # Don't use ''.join() because we want to test the ITERATOR. - page = "" - for line in child: - page = page + line - assert ( (page == 'abc\r\nabc\r\n123\r\n123\r\n' or - page == 'abc\r\n123\r\nabc\r\n123\r\n') , - "iterator did not work. page=%s"%repr(page) ) - def test_readlines(self): - '''Note that on some slow or heavily loaded systems that the lines - coming back from 'cat' may come even after the EOF. - We except to see two copies of the lines we send 'cat'. - The first line is the TTY echo, the second line is from 'cat'. - Usually 'cat' will respond with 'abc' before we have a chance to - send the second line, '123'. If this does not happen then the - lines may appear out of order. This is technically not an error. - That's just the nature of asynchronous communication. - This is why the assert will allow either of the two possible - patterns to be returned by lineslined(). The (lame) alternative is - to put a long sleep between the two sendline() calls, but then - I have to make assumptions about how fast 'cat' can reply. - ''' - child = pexpect.spawn('cat') - child.sendline ("abc") - child.sendline ("123") - child.sendeof() - page = child.readlines() - page = ''.join(page) - assert ( (page == 'abc\r\nabc\r\n123\r\n123\r\n' or - page == 'abc\r\n123\r\nabc\r\n123\r\n'), - "readlines() did not work. page=%s"%repr(page) ) - def test_write (self): - child = pexpect.spawn('cat') - child.write('a') - child.write('\r') - assert child.readline() == 'a\r\n', "write() did not work" - def test_writelines (self): - child = pexpect.spawn('cat') - child.writelines(['abc','123','xyz','\r']) - child.sendeof() - line = child.readline() - assert line == 'abc123xyz\r\n', "writelines() did not work. line=%s"%repr(line) - def test_eof(self): - child = pexpect.spawn('cat') - child.sendeof() - try: - child.expect ('the unexpected') - except: - pass - assert child.eof(), "child.eof() did not return True" - def test_terminate(self): - child = pexpect.spawn('cat') - child.terminate(force=1) - assert child.terminated, "child.terminated is not True" - def test_bad_child_pid(self): - child = pexpect.spawn('cat') - child.terminate(force=1) - child.terminated = 0 # Force invalid state to test code - try: - child.isalive() - except pexpect.ExceptionPexpect, e: - pass - else: - self.fail ("child.isalive() should have raised a pexpect.ExceptionPexpect") - child.terminated = 1 # Force back to valid state so __del__ won't complain - def test_bad_arguments (self): - '''This tests that we get a graceful error when passing bad arguments.''' - try: - p = pexpect.spawn(1) - except pexpect.ExceptionPexpect, e: - pass - else: - self.fail ("pexpect.spawn(1) should have raised a pexpect.ExceptionPexpect.") - try: - p = pexpect.spawn('ls', '-la') # should really use pexpect.spawn('ls', ['-ls']) - except TypeError, e: - pass - else: - self.fail ("pexpect.spawn('ls', '-la') should have raised a TypeError.") - try: - p = pexpect.spawn('cat') - p.close() - p.read_nonblocking(size=1, timeout=3) - except ValueError, e: - pass - else: - self.fail ("read_nonblocking on closed spawn object should have raised a ValueError.") - def test_isalive(self): - child = pexpect.spawn('cat') - assert child.isalive(), "child.isalive() did not return True" - child.sendeof() - child.expect(pexpect.EOF) - assert not child.isalive(), "child.isalive() did not return False" - def test_bad_type_in_expect(self): - child = pexpect.spawn('cat') - try: - child.expect({}) # We don't support dicts yet. Should give TypeError - except TypeError, e: - pass - else: - self.fail ("child.expect({}) should have raised a TypeError") - def test_winsize(self): - child = pexpect.spawn('cat') - child.setwinsize(10,13) - assert child.getwinsize()==(10,13), "getwinsize() did not return (10,13)" - def test_env(self): - default = pexpect.run('env') - userenv = pexpect.run('env', env={'foo':'pexpect'}) - assert default!=userenv, "'default' and 'userenv' should be different" - assert 'foo' in userenv and 'pexpect' in userenv, "'foo' and 'pexpect' should be in 'userenv'" - def test_cwd (self): # This assumes 'pwd' and '/tmp' exist on this platform. - default = pexpect.run('pwd') - tmpdir = pexpect.run('pwd', cwd='/tmp') - assert default!=tmpdir, "'default' and 'tmpdir' should be different" - assert ('tmp' in tmpdir), "'tmp' should be returned by 'pwd' command" - def test_which (self): - p = os.defpath - ep = os.environ['PATH'] - os.defpath = ":/tmp" - os.environ['PATH'] = ":/tmp" - wp = pexpect.which ("ticker.py") - assert wp == 'ticker.py', "Should return a string. Returned %s" % wp - os.defpath = "/tmp" - os.environ['PATH'] = "/tmp" - wp = pexpect.which ("ticker.py") - assert wp == None, "Executable should not be found. Returned %s" % wp - os.defpath = p - os.environ['PATH'] = ep - def test_searcher_re (self): - ss = pexpect.searcher_re ([re.compile('this'),re.compile('that'),re.compile('and'),re.compile('the'),re.compile('other')]) - assert ss.__str__() == 'searcher_re:\n 0: re.compile("this")\n 1: re.compile("that")\n 2: re.compile("and")\n 3: re.compile("the")\n 4: re.compile("other")' - ss = pexpect.searcher_re ([pexpect.TIMEOUT,re.compile('this'),re.compile('that'),re.compile('and'),pexpect.EOF,re.compile('other')]) - assert ss.__str__() == 'searcher_re:\n 0: TIMEOUT\n 1: re.compile("this")\n 2: re.compile("that")\n 3: re.compile("and")\n 4: EOF\n 5: re.compile("other")' - def test_searcher_string (self): - ss = pexpect.searcher_string (['this','that','and','the','other']) - assert ss.__str__() == 'searcher_string:\n 0: "this"\n 1: "that"\n 2: "and"\n 3: "the"\n 4: "other"', repr(ss.__str__()) - ss = pexpect.searcher_string (['this',pexpect.EOF,'that','and','the','other',pexpect.TIMEOUT]) - assert ss.__str__() == 'searcher_string:\n 0: "this"\n 1: EOF\n 2: "that"\n 3: "and"\n 4: "the"\n 5: "other"\n 6: TIMEOUT' - -if __name__ == '__main__': - unittest.main() - -suite = unittest.makeSuite(TestCaseMisc,'test') - diff --git a/pexpect/tests/test_missing_command.py b/pexpect/tests/test_missing_command.py deleted file mode 100755 index fea9218..0000000 --- a/pexpect/tests/test_missing_command.py +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import pexpect -import unittest -import PexpectTestCase - -class MissingCommandTestCase (PexpectTestCase.PexpectTestCase): - def testMissingCommand(self): - try: - i = pexpect.spawn ('ZXQYQZX') - except Exception: - pass - else: - self.fail('Expected an Exception.') - -if __name__ == '__main__': - unittest.main() - -suite = unittest.makeSuite(MissingCommandTestCase,'test') - diff --git a/pexpect/tests/test_performance.py b/pexpect/tests/test_performance.py deleted file mode 100755 index 50bb12f..0000000 --- a/pexpect/tests/test_performance.py +++ /dev/null @@ -1,91 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import unittest, time -import pexpect -import PexpectTestCase - -# This isn't exactly a unit test, but it fits in nicely with the rest of the tests. - -class PerformanceTestCase (PexpectTestCase.PexpectTestCase): - - '''Testing the performance of expect, with emphasis on wading through long - inputs. ''' - - def plain_range(self, n): - e = pexpect.spawn('python') - self.assertEqual(e.expect('>>>'), 0) - e.sendline('for n in range(1, %d+1): print n' % n) - self.assertEqual(e.expect(r'\.{3}'), 0) - e.sendline('') - self.assertEqual(e.expect(['inquisition', '%d' % n]), 1) - - def window_range(self, n): - e = pexpect.spawn('python') - self.assertEqual(e.expect('>>>'), 0) - e.sendline('for n in range(1, %d+1): print n' % n) - self.assertEqual(e.expect(r'\.{3}'), 0) - e.sendline('') - self.assertEqual(e.expect(['inquisition', '%d' % n], searchwindowsize=10), 1) - - def exact_range(self, n): - e = pexpect.spawn('python') - self.assertEqual(e.expect_exact(['>>>']), 0) - e.sendline('for n in range(1, %d+1): print n' % n) - self.assertEqual(e.expect_exact(['...']), 0) - e.sendline('') - self.assertEqual(e.expect_exact(['inquisition', '%d' % n],timeout=520), 1) - - def ewin_range(self, n): - e = pexpect.spawn('python') - self.assertEqual(e.expect_exact(['>>>']), 0) - e.sendline('for n in range(1, %d+1): print n' % n) - self.assertEqual(e.expect_exact(['...']), 0) - e.sendline('') - self.assertEqual(e.expect_exact(['inquisition', '%d' % n], searchwindowsize=10), 1) - - def faster_range(self, n): - e = pexpect.spawn('python') - self.assertEqual(e.expect('>>>'), 0) - e.sendline('range(1, %d+1)' % n) - self.assertEqual(e.expect(['inquisition', '%d' % n]), 1) - - def test_100000(self): - start_time = time.time() - self.plain_range (100000) - print "100000 calls to plain_range:", (time.time() - start_time) - start_time = time.time() - self.window_range(100000) - print "100000 calls to window_range:", (time.time() - start_time) - start_time = time.time() - self.exact_range (100000) - print "100000 calls to exact_range:", (time.time() - start_time) - start_time = time.time() - self.ewin_range (100000) - print "100000 calls to ewin_range:", (time.time() - start_time) - start_time = time.time() - self.faster_range(100000) - print "100000 calls to faster_range:", (time.time() - start_time) - -if __name__ == "__main__": - unittest.main() - -suite = unittest.makeSuite(PerformanceTestCase,'test') diff --git a/pexpect/tests/test_run.py b/pexpect/tests/test_run.py deleted file mode 100755 index 261bcb0..0000000 --- a/pexpect/tests/test_run.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import pexpect -import unittest -import commands -import sys -import PexpectTestCase - -# TODO Many of these test cases blindly assume that sequential -# TODO listing of the /bin directory will yield the same results. -# TODO This may not always be true, but seems adequate for testing for now. -# TODO I should fix this at some point. - -def timeout_callback (d): -# print d["event_count"], - if d["event_count"]>5: - return 1 - return 0 - -class ExpectTestCase(PexpectTestCase.PexpectTestCase): - def test_run_exit (self): - (data, exitstatus) = pexpect.run ('python exit1.py', withexitstatus=1) - assert exitstatus == 1, "Exit status of 'python exit1.py' should be 1." - - def test_run (self): - the_old_way = commands.getoutput('ls -l /bin') - (the_new_way, exitstatus) = pexpect.run ('ls -l /bin', withexitstatus=1) - the_new_way = the_new_way.replace('\r','')[:-1] - assert the_old_way == the_new_way - assert exitstatus == 0 - - def test_run_callback (self): # TODO it seems like this test could block forever if run fails... - pexpect.run("cat", timeout=1, events={pexpect.TIMEOUT:timeout_callback}) - - def test_run_bad_exitstatus (self): - (the_new_way, exitstatus) = pexpect.run ('ls -l /najoeufhdnzkxjd', withexitstatus=1) - assert exitstatus != 0 - -if __name__ == '__main__': - unittest.main() - -suite = unittest.makeSuite(ExpectTestCase,'test') - diff --git a/pexpect/tests/test_run_out_of_pty.py b/pexpect/tests/test_run_out_of_pty.py deleted file mode 100755 index b6b9e6c..0000000 --- a/pexpect/tests/test_run_out_of_pty.py +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import pexpect -import unittest -import commands -import sys -import PexpectTestCase - -class ExpectTestCase(PexpectTestCase.PexpectTestCase): - # This takes too long to run and isn't all that interesting of a test. - def OFF_test_run_out_of_pty (self): - '''This assumes that the tested platform has < 10000 pty devices. - This test currently does not work under Solaris. - Under Solaris it runs out of file descriptors first and - ld.so starts to barf: - ld.so.1: pt_chmod: fatal: /usr/lib/libc.so.1: Too many open files - ''' - plist=[] - for count in range (0,10000): - try: - plist.append (pexpect.spawn('ls -l')) - except pexpect.ExceptionPexpect, e: - for c in range (0,count): - plist[c].close() - return - except Exception, e: - self.fail ('Expected ExceptionPexpect. ' + str(e)) - self.fail ('Could not run out of pty devices. This may be OK.') - -if __name__ == '__main__': - unittest.main() - -suite = unittest.makeSuite(ExpectTestCase,'test') - diff --git a/pexpect/tests/test_screen.py b/pexpect/tests/test_screen.py deleted file mode 100755 index 714f85e..0000000 --- a/pexpect/tests/test_screen.py +++ /dev/null @@ -1,191 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import screen -import unittest -import PexpectTestCase - -fill1_target='XXXXXXXXXX\n' + \ -'XOOOOOOOOX\n' + \ -'XO::::::OX\n' + \ -'XO:oooo:OX\n' + \ -'XO:o..o:OX\n' + \ -'XO:o..o:OX\n' + \ -'XO:oooo:OX\n' + \ -'XO::::::OX\n' + \ -'XOOOOOOOOX\n' + \ -'XXXXXXXXXX' -fill2_target = 'XXXXXXXXXXX\n' + \ -'XOOOOOOOOOX\n' + \ -'XO:::::::OX\n' + \ -'XO:ooooo:OX\n' + \ -'XO:o...o:OX\n' + \ -'XO:o.+.o:OX\n' + \ -'XO:o...o:OX\n' + \ -'XO:ooooo:OX\n' + \ -'XO:::::::OX\n' + \ -'XOOOOOOOOOX\n' + \ -'XXXXXXXXXXX' -put_target = '\\.3.5.7.9/\n' + \ -'.........2\n' + \ -'3.........\n' + \ -'.........4\n' + \ -'5...\\/....\n' + \ -'..../\\...6\n' + \ -'7.........\n' + \ -'.........8\n' + \ -'9.........\n' + \ -'/2.4.6.8.\\' -scroll_target = '\\.3.5.7.9/\n' + \ -'\\.3.5.7.9/\n' + \ -'\\.3.5.7.9/\n' + \ -'\\.3.5.7.9/\n' + \ -'5...\\/....\n' + \ -'..../\\...6\n' + \ -'/2.4.6.8.\\\n' + \ -'/2.4.6.8.\\\n' + \ -'/2.4.6.8.\\\n' + \ -'/2.4.6.8.\\' -insert_target = 'ZXZZZZZZXZ\n' +\ -'.........2\n' +\ -'3.........\n' +\ -'.........4\n' +\ -'Z5...\\/...\n' +\ -'..../Z\\...\n' +\ -'7.........\n' +\ -'.........8\n' +\ -'9.........\n' +\ -'ZZ/2.4.6ZZ' -get_region_target = ['......', '.\\/...', './\\...', '......'] - -class screenTestCase (PexpectTestCase.PexpectTestCase): - def make_screen_with_put (self): - s = screen.screen(10,10) - s.fill ('.') - for r in range (1,s.rows + 1): - if r % 2: - s.put_abs (r, 1, str(r)) - else: - s.put_abs (r, s.cols, str(r)) - for c in range (1,s.cols + 1): - if c % 2: - s.put_abs (1, c, str(c)) - else: - s.put_abs (s.rows, c, str(c)) - s.put_abs(1,1, '\\') - s.put_abs(1,s.cols, '/') - s.put_abs(s.rows,1,'/') - s.put_abs(s.rows, s.cols, '\\') - s.put_abs(5,5,'\\') - s.put_abs(5,6,'/') - s.put_abs(6,5,'/') - s.put_abs(6,6,'\\') - return s - - def test_fill (self): - s = screen.screen (10,10) - s.fill_region (10,1,1,10,'X') - s.fill_region (2,2,9,9,'O') - s.fill_region (8,8,3,3,':') - s.fill_region (4,7,7,4,'o') - s.fill_region (6,5,5,6,'.') - assert str(s) == fill1_target - - s = screen.screen (11,11) - s.fill_region (1,1,11,11,'X') - s.fill_region (2,2,10,10,'O') - s.fill_region (9,9,3,3,':') - s.fill_region (4,8,8,4,'o') - s.fill_region (7,5,5,7,'.') - s.fill_region (6,6,6,6,'+') - assert str(s) == fill2_target - def test_put (self): - s = self.make_screen_with_put() - assert str(s) == put_target - def test_get_region (self): - s = self.make_screen_with_put() - r = s.get_region (4,4,7,9) - assert r == get_region_target - - def test_cursor_save (self): - s = self.make_screen_with_put() - s.cursor_home (5,5) - c = s.get() - s.cursor_save() - s.cursor_home() - s.cursor_forward() - s.cursor_down() - s.cursor_unsave() - assert s.cur_r == 5 and s.cur_c == 5 - assert c == s.get() - def test_scroll (self): - s = self.make_screen_with_put() - s.scroll_screen_rows (1,4) - s.scroll_down(); s.scroll_down(); s.scroll_down() - s.scroll_down(); s.scroll_down(); s.scroll_down() - s.scroll_screen_rows (7,10) - s.scroll_up(); s.scroll_up(); s.scroll_up() - s.scroll_up(); s.scroll_up(); s.scroll_up() - assert str(s) == scroll_target - def test_insert (self): - s = self.make_screen_with_put() - s.insert_abs (10,1,'Z') - s.insert_abs (1,1,'Z') - s.insert_abs (1,1,'Z') - s.insert_abs (1,1,'Z') - s.insert_abs (1,1,'Z') - s.insert_abs (1,1,'Z') - s.insert_abs (10,1,'Z') - s.insert_abs (1,1,'Z') - s.insert_abs (1,1,'Z') - s.insert_abs (5,1,'Z') - s.insert_abs (6,6,'Z') - s.cursor_home (1,1) # Also test relative insert. - s.insert ('Z') - s.insert ('Z') - s.insert ('Z') - s.insert ('Z') - s.insert_abs (1,8,'X') - s.insert_abs (1,2,'X') - s.insert_abs (10,9,'Z') - s.insert_abs (10,9,'Z') - assert str(s) == insert_target - # def test_write (self): - # s = screen.screen (6,65) - # s.fill('.') - # s.cursor_home() - # for c in write_text: - # s.write (c) - # print str(s) - # assert str(s) == write_target - # def test_tetris (self): - # s = screen.screen (24,80) - # tetris_text = open ('tetris.data').read() - # for c in tetris_text: - # s.write (c) - # assert str(s) == tetris_target - -if __name__ == '__main__': - unittest.main() - -suite = unittest.makeSuite(screenTestCase,'test') - - diff --git a/pexpect/tests/test_timeout_pattern.py b/pexpect/tests/test_timeout_pattern.py deleted file mode 100755 index 606b045..0000000 --- a/pexpect/tests/test_timeout_pattern.py +++ /dev/null @@ -1,86 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import pexpect -import unittest -import sys, os, time -import PexpectTestCase - -class Exp_TimeoutTestCase(PexpectTestCase.PexpectTestCase): - def test_matches_exp_timeout (self): - '''This tests that we can raise and catch TIMEOUT. - ''' - try: - raise pexpect.TIMEOUT("TIMEOUT match test") - except pexpect.TIMEOUT: - pass - #print "Correctly caught TIMEOUT when raising TIMEOUT." - else: - self.fail('TIMEOUT not caught by an except TIMEOUT clause.') - - def test_pattern_printout (self): - '''Verify that a TIMEOUT returns the proper patterns it is trying to match against. - Make sure it is returning the pattern from the correct call.''' - try: - p = pexpect.spawn('cat') - p.sendline('Hello') - p.expect('Hello') - p.expect('Goodbye',timeout=5) - except pexpect.TIMEOUT, expTimeoutInst: - assert p.match_index == None - else: - self.fail("Did not generate a TIMEOUT exception.") - - def test_exp_timeout_notThrown (self): - '''Verify that a TIMEOUT is not thrown when we match what we expect.''' - try: - p = pexpect.spawn('cat') - p.sendline('Hello') - p.expect('Hello') - except pexpect.TIMEOUT: - self.fail("TIMEOUT caught when it shouldn't be raised because we match the proper pattern.") - - def test_stacktraceMunging (self): - '''Verify that the stack trace returned with a TIMEOUT instance does not contain references to pexpect.''' - try: - p = pexpect.spawn('cat') - p.sendline('Hello') - p.expect('Goodbye',timeout=5) - except pexpect.TIMEOUT, e: - if e.get_trace().count("pexpect.py") != 0: - self.fail("The TIMEOUT get_trace() referenced pexpect.py. It should only reference the caller.\n"+e.get_trace()) - - def test_correctStackTrace (self): - '''Verify that the stack trace returned with a TIMEOUT instance correctly handles function calls.''' - def nestedFunction (spawnInstance): - spawnInstance.expect("junk", timeout=3) - - try: - p = pexpect.spawn('cat') - p.sendline('Hello') - nestedFunction(p) - except pexpect.TIMEOUT, e: - if e.get_trace().count("nestedFunction") == 0: - self.fail("The TIMEOUT get_trace() did not show the call to the nestedFunction function.\n" + str(e) + "\n" + e.get_trace()) - -if __name__ == '__main__': - unittest.main() - -suite = unittest.makeSuite(Exp_TimeoutTestCase,'test') diff --git a/pexpect/tests/test_winsize.py b/pexpect/tests/test_winsize.py deleted file mode 100755 index 4888641..0000000 --- a/pexpect/tests/test_winsize.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import pexpect -import unittest -import PexpectTestCase -import time -import sys, os, signal - -class TestCaseWinsize(PexpectTestCase.PexpectTestCase): - - def test_winsize (self): - ''' - This tests that the child process can set and get the windows size. - This makes use of an external script sigwinch_report.py. - ''' - p1 = pexpect.spawn('%s sigwinch_report.py' % self.PYTHONBIN) - time.sleep(10) - p1.setwinsize (11,22) - time.sleep(3) - index = p1.expect ([pexpect.TIMEOUT, 'SIGWINCH: \(([0-9]*), ([0-9]*)\)'], timeout=30) - if index == 0: - self.fail ("TIMEOUT -- this platform may not support sigwinch properly.\n" + str(p1)) - r = p1.match.group(1) - c = p1.match.group(2) - assert (r=="11" and c=="22") - time.sleep(1) - p1.setwinsize (24,80) - index = p1.expect ([pexpect.TIMEOUT, 'SIGWINCH: \(([0-9]*), ([0-9]*)\)'], timeout=10) - if index == 0: - self.fail ("TIMEOUT -- this platform may not support sigwinch properly.\n" + str(p1)) - r = p1.match.group(1) - c = p1.match.group(2) - assert (r=="24" and c=="80") - p1.close() - -# def test_parent_resize (self): -# pid = os.getpid() -# p1 = pexpect.spawn('%s sigwinch_report.py' % self.PYTHONBIN) -# time.sleep(10) -# p1.setwinsize (11,22) -# os.kill (pid, signal.SIGWINCH) - -if __name__ == '__main__': - unittest.main() - -suite = unittest.makeSuite(TestCaseWinsize,'test') - - diff --git a/pexpect/tests/tetris.data b/pexpect/tests/tetris.data deleted file mode 100644 index 06b6ce6..0000000 --- a/pexpect/tests/tetris.data +++ /dev/null @@ -1,3 +0,0 @@ -[2J -[24;1H J->LEFT K->ROTATE L->RIGHT SPACE->DROP P->PAUSE Q->QUIT -[1;28HXX[1;36HXXXXXXXX[1;50HXX[2;28HXX[2;50HXX[3;28HXX[3;50HXX[4;28HXX[4;50HXX[5;28HXX[5;50HXX[6;28HXX[6;50HXX[7;28HXX[7;50HXX[8;28HXX[8;50HXX[9;28HXX[9;50HXX[10;28HXX[10;50HXX[11;28HXX[11;50HXX[12;28HXX[12;50HXX[13;28HXX[13;50HXX[14;28HXX[14;50HXX[15;28HXX[15;50HXX[16;28HXX[16;50HXX[17;28HXX[17;50HXX[18;28HXX[18;50HXX[19;28HXX[19;50HXX[20;28HXX[20;50HXX[21;28HXXXXXXXXXXXXXXXXXXXXXXXX[1;36H [2;36HXXXXXXXX[21;50HXX[2;36H [3;36HXXXXXXXX[21;50HXX[3;36H [4;36HXXXXXXXX[21;50HXX[4;36H [5;36HXXXXXXXX[21;50HXX[5;34HXX[5;42H [21;50HXX[5;34H [6;34HXXXXXXXX[21;50HXX[6;32HXX[6;40H [21;50HXX[6;30HXX[6;38H [21;50HXX[6;30H [7;30HXXXXXXXX[21;50HXX[21;50HXX[21;50HXX[21;50HXX[7;30H [8;30HXXXXXXXX[21;50HXX[8;30H [20;30HXXXXXXXX[21;50HXX[1;36HXXXXXX[2;36HXX[21;50HXX[1;36H [2;38HXXXX[3;36HXX[21;50HXX[2;36H [2;42HXX[3;36H XX[21;50HXX[2;38H [3;40HXXXX[4;38HXX[21;50HXX[3;38H [3;44HXX[4;38H XX[21;50HXX[3;40H [3;46HXX[4;40H XX[21;50HXX[3;42H [3;48HXX[4;42H XX[21;50HXX[21;50HXX[21;50HXX[21;50HXX[21;50HXX[21;50HXX[21;50HXX[3;44H [4;46HXXXX[5;44HXX[21;50HXX[4;44H [5;46HXXXX[6;44HXX[21;50HXX[5;44H [6;44H [19;44HXXXXXX[20;44HXX[21;50HXX[1;36HXXXXXX[2;36HXX[21;50HXX[1;36H [2;38HXXXX[3;36HXX[21;50HXX[2;36H [2;42HXX[3;36H XX[21;50HXX[2;38H [2;44HXX[3;38H XX[21;50HXX[2;40H [3;42HXXXX[4;40HXX[21;50HXX[2;42HXX[3;40H [3;44H [4;40H XXXX[21;50HXX[2;42H XX[3;40HXX[3;44HXX[4;42H [21;50HXX[2;44H [3;40H [4;40HXXXXXX[21;50HXX[3;44H [4;40H [17;44HXX[18;40HXXXXXX[21;50HXX[1;36HXXXX[21;50HXX[1;36H [1;40HXX[2;36HXXXX[21;50HXX[1;36HXX[1;40H [2;34HXX[2;38H [21;50HXX[1;36H [2;34H [2;38HXX[3;34HXXXX[21;50HXX[2;34HXX[2;38H [3;32HXX[3;36H [21;50HXX[2;32HXX[2;36H [3;30HXX[3;34H [21;50HXX[21;50HXX[2;32H [3;30H [3;34HXX[4;30HXXXX[21;50HXX[21;50HXX[3;32H [4;30H [18;32HXXXX[19;30HXXXX[21;50HXX[1;36HXXXXXX[2;36HXX[21;50HXX[1;36H [1;42HXX[2;36H XX[21;50HXX[1;38H [2;40HXXXX[3;38HXX[21;50HXX[2;38H [2;44HXX[3;38H XX[21;50HXX[2;40H [2;46HXX[3;40H XX[21;50HXX[2;42H [2;48HXX[3;42H XX[21;50HXX[2;44H [3;46HXXXX[4;44HXX[21;50HXX[21;50HXX[21;50HXX[3;44H [4;44H [15;44HXXXXXX[16;44HXX[21;50HXX[1;36HXXXXXXXX[21;50HXX[1;34HXX[1;42H [21;50HXX[1;34H [2;34HXXXXXXXX[21;50HXX[2;32HXX[2;40H [21;50HXX[2;30HXX[2;38H [21;50HXX[21;50HXX[21;50HXX[21;50HXX[21;50HXX[2;30H [3;30HXXXXXXXX[21;50HXX[3;30H [17;30HXXXXXXXX[21;50HXX[1;38HXXXX[21;50HXX[1;38H [16;36HXXXX[17;38HXXXX[21;50HXX[21;50HXX[1;36HXXXX[21;50HXX[1;36H [1;40HXX[21;50HXX[2;38HXXXX[21;50HXX[1;38H [1;42HXX[2;38H [2;42HXX[21;50HXX[1;40H [1;44HXX[2;40H [2;44HXX[21;50HXX[1;42H [1;46HXX[2;42H [2;46HXX[21;50HXX[1;44H [3;44HXXXX[21;50HXX[2;44H [3;44H [13;44HXXXX[14;44HXXXX[21;50HXX[1;36HXXXXXX[2;40HXX[21;50HXX[1;34HXX[1;40H [2;38HXX [21;50HXX[1;34H [2;34HXXXX[3;38HXX[21;50HXX[2;32HXX[2;38H [3;36HXX [21;50HXX[2;30HXX[2;36H [3;34HXX [21;50HXX[21;50HXX[21;50HXX[21;50HXX[2;30H [3;34H [15;30HXXXXXX[16;34HXX[21;50HXX[1;36HXXXXXXXX[21;50HXX[1;36H [1;44HXX[21;50HXX[1;38H [2;38HXXXXXXXX[21;50HXX[1;40HXX[2;38H [2;42H [3;40HXX[4;40HXX[21;50HXX[1;40H [5;40HXX[21;50HXX[2;40H [3;38HXX[3;42HXXXX[4;40H [5;40H [21;50HXX[2;40HXX[3;38H [3;42H [4;40HXX[5;40HXX[21;50HXX[2;40H [6;40HXX[21;50HXX[3;40H [4;40H [5;40H [6;40H [13;40HXX[14;40HXX[15;40HXX[16;40HXX[21;50HXX[1;36HXXXXXX[2;38HXX[21;50HXX[1;34HXX[1;40H [2;36HXX [21;50HXX[1;32HXX[1;38H [2;34HXX [21;50HXX[1;32H [21;50HXX[1;36H [2;36HXX[3;34HXX[21;50HXX[1;32HXX [2;32HXX[2;36H [3;32HXX [21;50HXX[2;30HXX[3;32H [21;50HXX[1;32H [2;30H [2;34H [3;30HXXXXXX[21;50HXX[2;32H [3;30H [13;32HXX[14;30HXXXXXX[21;50HXX[1;36HXXXXXXXX[21;50HXX[1;36H [1;44HXX[21;50HXX[1;38H [1;42H [2;40HXX[3;40HXX[21;50HXX[1;40H XX[2;40H XX[3;40H XX[21;50HXX[4;42HXX[21;50HXX[1;42H [2;40HXX[2;44HXXXX[3;42H [4;42H [21;50HXX[2;40H [2;48HXX[21;50HXX[1;44HXX[2;42H [2;46H [3;44HXX[4;44HXX[21;50HXX[1;44H [5;44HXX[21;50HXX[2;44H [3;44H [4;44H [5;44H [9;44HXX[10;44HXX[11;44HXX[12;44HXX[21;50HXX[1;36HXXXXXX[2;36HXX[21;50HXX[1;36H [1;40H [2;36H XXXX[21;50HXX[1;36HXX [2;36HXX[2;40H [21;50HXX[1;34HXX[1;38HXX[2;36H [21;50HXX[1;34H [2;34HXXXXXX[21;50HXX[1;36HXX [2;32HXX[2;38H [21;50HXX[1;32HXXXX [2;32H [2;36H [3;34HXX[21;50HXX[1;30HXX[1;34H [2;32HXX [3;32HXX [21;50HXX[1;30H [2;30HXX[4;32HXX[21;50HXX[2;30H [3;32H [4;32H [10;30HXXXX[11;32HXX[12;32HXX[21;50HXX[1;36HXXXXXX[2;40HXX[21;50HXX[1;36H [1;40H [2;38HXX [21;50HXX[1;36HXX[1;40HXX[2;38H [21;50HXX[1;38H [2;36HXXXXXX[21;50HXX[1;36H XX[2;36H [2;40H [3;36HXXXX[21;50HXX[1;38H [2;38H [3;36H [13;38HXX[14;38HXX[15;36HXXXX[21;50HXX[1;36HXXXXXX[2;36HXX[21;50HXX[1;36H [1;42HXX[2;36H XX[21;50HXX[1;38H [2;40HXXXX[3;38HXX[21;50HXX[1;40HXX[2;38H [2;42H [3;38H XXXX[21;50HXX[1;40H XX[2;40H XX[3;40H [3;44HXX[21;50HXX[1;42H XX[2;40HXX[2;44HXX[3;42H [21;50HXX[1;44H XX[2;40H [2;46HXX[21;50HXX[1;46H [2;42H [3;42HXXXXXX[21;50HXX[2;42HXXXX [3;42H [3;46H [4;44HXX[21;50HXX[2;42H [3;44H [4;44H [6;42HXXXX[7;44HXX[8;44HXX[21;50HXX[1;38HXXXX[21;50HXX[1;36HXX[1;40H [2;36HXX[21;50HXX[1;34HXX[1;38H [2;34HXX [21;50HXX[1;34H [2;36HXX[3;34HXX[21;50HXX[1;34HXX[2;34H [2;38HXX[3;34H [21;50HXX[1;32HXX[1;36H [2;34HXX[2;38H [21;50HXX[1;32H [2;32HXX[2;36H [3;32HXX[21;50HXX[1;32HXX [2;30HXX[2;34H [3;30HXX [21;50HXX[1;32H [2;30H [3;32HXX[4;30HXX[21;50HXX[2;32H [3;30H [4;30H [7;32HXX[8;30HXXXX[9;30HXX[21;50HXX[1;36HXXXX[21;50HXX[21;50HXX[1;36H [1;40HXX[21;50HXX[21;50HXX[2;38HXXXX[21;50HXX[1;38H [1;42HXX[2;38H [2;42HXX[21;50HXX[21;50HXX[1;40H [1;44HXX[2;40H [2;44HXX[21;50HXX[21;50HXX[1;42H [3;42HXXXX[21;50HXX[2;42H [3;42H [4;42HXXXX[5;42HXXXX[21;50HXX[1;36HXXXX[21;50HXX[1;36H [1;40HXX[2;40HXX[21;50HXX[1;36HXX[1;40H [2;40H [21;50HXX[1;36H [1;40HXX[2;40HXX[21;50HXX[1;40H [2;38HXX[3;40HXX[21;50HXX[1;38H [2;38H [3;40H [10;38HXX[11;38HXXXX[12;40HXX[21;50HXX[1;36HXXXXXX[2;40HXX[21;50HXX[1;36H [2;40H [9;36HXXXXXX[10;40HXX[21;50HXX[21;50HXX[1;38HXXXX[21;50HXX[1;36HXX[1;40H [2;36HXX[21;50HXX[1;34HXX[1;38H [2;34HXX [21;50HXX[1;34H [2;36HXX[3;34HXX[21;50HXX[1;34HXX[2;34H [2;38HXX[3;34H [21;50HXX[1;32HXX[1;36H [2;34HXX[2;38H [21;50HXX[1;32H [2;34H [6;32HXXXX[7;34HXXXX[21;50HXX[1;36HXXXXXX[2;40HXX[21;50HXX[1;36H [1;42HXX[2;40H XX[21;50HXX[1;38H [1;42H [2;40HXX [21;50HXX[1;40H XX[2;40H XX[21;50HXX[1;40HXX[1;44HXX[2;42H [21;50HXX[1;42H [2;40HXXXXXX[21;50HXX[1;40H XX[2;40H [2;46HXX[21;50HXX[1;42H XX[2;42H [2;46H [3;42HXXXX[21;50HXX[21;50HXX[1;38HXXXX[21;50HXX[1;36HXX[1;40H [2;36HXX[21;50HXX[1;36H [2;38HXX[3;36HXX[21;50HXX[1;36HXX [2;34HXX[2;38H [3;34HXX [21;50HXX[1;34HXX[2;34H [2;38HXX[3;34H [21;50HXX[1;32HXX[1;36H [2;34HXX[2;38H [21;50HXX[1;32H [2;32HXX[2;36H [3;32HXX[21;50HXX[1;34H [2;32H [3;34HXX[4;32HXX[21;50HXX[2;32HXX [3;30HXX[3;34H [4;30HXX [21;50HXX[2;32H [3;30H [4;30H XX[5;30HXXXX[6;30HXX[21;50HXX[1;36HXXXXXX[2;40HXX[21;50HXX[1;36H [1;42HXX[2;40H XX[21;50HXX[1;38H [1;42H [2;40HXX [21;50HXX[1;40H XX[2;40H XX[21;50HXX[21;50HXX[1;38HXXXX[21;50HXX[21;50HXX[1;36HXX[1;40H [2;36HXX[21;50HXX[1;36H [2;36H [4;38HXX[5;36HXXXX[6;36HXX[21;50HXX[1;36HXXXX[21;50HXX[21;50HXX[1;34HXX[1;38H [21;50HXX[2;34HXXXX[21;50HXX[21;50HXX[1;32HXX[1;36H [2;32HXX[2;36H [21;50HXX[21;50HXX[1;30HXX[1;34H [2;30HXX[2;34H [21;50HXX[1;30H [3;30HXXXX[21;50HXX[21;50HXX[1;36HXXXX[21;50HXX[1;36H [1;40HXX[21;50HXX[21;50HXX[21;50HXX[21;50HXX[2;38HXXXX[21;50HXX[21;50HXX[21;50HXX[21;50HXX[21;50HXX[1;38H [3;38HXXXX[21;50HXX[21;50HXX[21;50HXX[21;50HXX[21;50HXX diff --git a/pexpect/tests/ticker.py b/pexpect/tests/ticker.py deleted file mode 100755 index 5ecc1c2..0000000 --- a/pexpect/tests/ticker.py +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env python -''' -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import time, sys - -for i in range(5): - print "tick" - time.sleep(1) - -sys.exit(0) diff --git a/pexpect/tests/torturet.vt b/pexpect/tests/torturet.vt deleted file mode 100644 index 65f965b..0000000 --- a/pexpect/tests/torturet.vt +++ /dev/null @@ -1,61 +0,0 @@ -\<>[H[1;2;3;4qPrEM1\[?4h[0m -[H[J[7m#6(0a`opqrs`(B This is the (0`srqpo`a(B[1m -#3VT100 series Torture Test Demonstration. -#4VT100 series Torture Test Demonstration. -#6[1;5m Watch the blinking lights [4;24r[0m -[0q[1q[0q[2q[0q[3q[0q[4q[0q -[0q[1q[0q[2q[0q[3q[0q[4q[0q -[0q[1q[0q[2q[0q[3q[0q[4q[0q -PrEM0\[4;1H[J[24;1H - -This file is a VT100-series Torture Test. It demonstrates all the visual -attributes of the VT100 terminal. - -The top line is double-width/single-height with inverse-video line-drawing -characters. The 2nd and 3rd lines are double-width/double-height in bold -inverse video. They also show the limited scrolling region. - -The remaining lines will show NORMAL, BOLD, BLINK, INVERSE, and all 16 -combinations of those 4 attributes. They show that there is a difference -between an underscore character and the underline attribute, and that -lower-case decenders go below the underline. - -A window pane is drawn in the lower right to show how the line-drawing set -can be used. At the lower left is the character set double-wide/double-high -to show the dot-matrix used. Upper-case characters are 8 by 7 in a 10 by 10 -character cell, with 1 blank row on top and 2 on the bottom. The underline -attribute uses the first bottom blank row, lower-case decenders use both. - - - -[0mThis is a normal line __________________________________________________y_ -[1mThis is a bold line (normal unless the Advanced Video Option is installed) -[0;4mThis line is underlined _ " " " " " " _y_ -[0;5mThis is a blinking line _ " " " " " " _y_ -[0;7mThis is inverse video _ (underlined if no AVO and cursor is underline) _y_ -[0mNormal gjpqy [4mUnderline[0;0m [5m Blink [4mUnderline+Blink gjpqy[0m -[1mBold gjpqy [4mUnderline[0;1m [5m Blink [4mUnderline+Blink gjpqy[0m -[7mInverse [4mUnderline[0;7m [5m Blink [4mUnderline+Blink[0;7m -[1mBold+Inverse [4mUnderline[0;1;7m [5m Blink [4mUnderline+Blink[0m -PrEM1\[A -#6This is double [1mwidth[0m -#3This is double [1mheight[0m -#4This is double [1mheight[0m -#6[7;4m_[0;7mABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ioy -#3[7;4m_[0;7mABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ioy -#4[7;4m_[0;7mABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789ioy[3A -[0m[CA[CC[CE[CG[CI[CK[CM[CO[CQ[CS[CU[CW[CY[C0[C2[C4[C6[C8[Ci[Cy -[4m_[0m[CB[CD[CF[CH[CJ[CL[CN[CP[CR[CT[CV[CX[CZ[C1[C3[C5[C7[C9[Co -[4m_[0m[CB[CD[CF[CH[CJ[CL[CN[CP[CR[CT[CV[CX[CZ[C1[C3[C5[C7[C9[Co -(0#6[7m`abcdefghijklmnopqrstuvwxyz{|}~[0m lqwqk -#3[7m`abcdefghijklmnopqrstuvwxyz{|}~[0m tqnqu -#4[7m`abcdefghijklmnopqrstuvwxyz{|}~[0m tqnqu[3A[0m -[Ca[Cc[Ce[Cg[Ci[Ck[Cm[Co[Cq[Cs[Cu[Cw[Cy[C{[C} -`[Cb[Cd[Cf[Ch[Cj[Cl[Cn[Cp[Cr[Ct[Cv[Cx[Cz[C|[C~ -`[Cb[Cd[Cf[Ch[Cj[Cl[Cn[Cp[Cr[Ct[Cv[Cx[Cz[C|[C~(B -#6[7m`abcdefghijklmnopqrstuvwxyz{|}~(0[0m mqvqj[A(B -[0m[Ca[Cc[Ce[Cg[Ci[Ck[Cm[Co[Cq[Cs[Cu[Cw[Cy[C{[C} -PrEM0\ $PrEM0 works on GIGI [A[1;7m - This test created by Joe Smith, 8-May-85 [0m -[1;r[22;1H - diff --git a/pexpect/tools/dotfiles.tar.gz b/pexpect/tools/dotfiles.tar.gz Binary files differdeleted file mode 100644 index 0636410..0000000 --- a/pexpect/tools/dotfiles.tar.gz +++ /dev/null diff --git a/pexpect/tools/getkey.py b/pexpect/tools/getkey.py deleted file mode 100755 index 76c07de..0000000 --- a/pexpect/tools/getkey.py +++ /dev/null @@ -1,46 +0,0 @@ -''' -This currently just holds some notes. -This is not expected to be working code. - -$Revision: 120 $ -$Date: 2002-11-27 11:13:04 -0800 (Wed, 27 Nov 2002) $ - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import tty, termios, sys - -def getkey(): - file = sys.stdin.fileno() - mode = termios.tcgetattr(file) - try: - tty.setraw(file, termios.TCSANOW) - ch = sys.stdin.read(1) - finally: - termios.tcsetattr(file, termios.TCSANOW, mode) - return ch - -def test_typing (): - s = screen (10,10) - while 1: - ch = getkey() - s.type(ch) - print str(s) - print - diff --git a/pexpect/tools/merge_templates.py b/pexpect/tools/merge_templates.py deleted file mode 100755 index accc8e9..0000000 --- a/pexpect/tools/merge_templates.py +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env python - -''' -I used to use this to keep the sourceforge pages up to date with the -latest documentation and I like to keep a copy of the distribution -on the web site so that it will be compatible with -The Vaults of Parnasus which requires a direct URL link to a -tar ball distribution. I don't advertise the package this way. - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -''' -import sys, os, re -import pyed -try: - import pexpect -except: - # this happens if Pexpect was never installed to begin with. - sys.path.insert(0, '.') - import pexpect - -# extract the version number from the pexpect.py source. -d = pyed.pyed() -d.read ("pexpect.py") -d.first('^__version__') -r = re.search("'([0-9]\.[0-9])'", d.cur_line) -version = r.group(1) - -# Edit the index.html to update current VERSION. -d = pyed.pyed() -d.read ("doc/index.template.html") -for cl in d.match_lines('.*VERSION.*'): - d.cur_line = d.cur_line.replace('VERSION', version) -d.write("doc/index.html") - -# Edit the setup.py to update current VERSION. -d = pyed.pyed() -d.read ("setup.py.template") -for cl in d.match_lines('.*VERSION.*'): - d.cur_line = d.cur_line.replace('VERSION', version) -d.write("setup.py") -os.chmod("setup.py", 0755) - diff --git a/pexpect/tools/pyed.py b/pexpect/tools/pyed.py deleted file mode 100755 index 14c562a..0000000 --- a/pexpect/tools/pyed.py +++ /dev/null @@ -1,180 +0,0 @@ -"""This represents a document with methods to allow easy editing. -Think 'sed', only more fun to use. -Example 1: Convert all python-style comments in a file to UPPERCASE. -This operates as a filter on stdin, so this needs a shell pipe. -cat myscript.py | upper_filter.py - import sys, pyed - pe = pyed() - pe.read(sys.stdin) - for pe in pe.match_lines('^\\s*#'): - pe.cur_line = pe.cur_line.upper() - print pe - -Example 2: Edit an Apache2 httpd.conf file to turn on supplemental SSL configuration. - import pyed - pe = pyed() - pe.read("httpd.conf") - pe.first('#Include conf/extra/httpd-ssl.conf') - pe.cur_line = 'Include conf/extra/httpd-ssl.conf' - pe.write("httpd.conf") - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -""" - -import re -class pyed (object): - def __init__ (self, new_str=None): - if new_str is not None: - self.lines = new_str.splitlines() - self.cur_line_num = 0 - else: - self.lines = None - # force invalid line number - self.cur_line_num = None - def match_lines (self, pattern, beg=0, end=None): - """This returns a generator that iterates this object - over the lines and yielding when a line matches the pattern. - Note that this generator mutates this object so that - the cur_line is changed to the line matching the pattern. - """ - p = re.compile (pattern) - if end is None: - end = len(self.lines) - for i in xrange (beg,end): - m = p.match(self.lines[i]) - if m is not None: - self.cur_line_num = i - yield self - else: - # force invalid line number - cur_line_num = None - def match_lines_rev (self, pattern, beg=0, end=None): - """This is similar to match_lines, but the order is reversed. - """ - p = re.compile (pattern) - if end is None: - end = len(self.lines) - for i in xrange (end-1,beg-1,-1): - m = p.match(self.lines[i]) - if m is not None: - self.cur_line_num = i - yield self - else: - # force invalid line number - cur_line_num = None - def next (self): - self.cur_line_num = self.cur_line_num + 1 - if self.cur_line_num >= len(self.lines): - self.cur_line_num = len(self.lines) - 1 - return self.cur_line - def prev (self): - self.cur_line_num = self.cur_line_num - 1 - if self.cur_line_num < 0: - self.cur_line_num = 0 - return self.cur_line - def first (self, pattern=None): - if pattern is not None: - try: - return self.match_lines(pattern).next() - except StopIteration, e: - # force invalid line number - self.cur_line_num = None - return None - self.cur_line_num = 0 - return self.cur_line - def last (self, pattern=None): - if pattern is not None: - try: - return self.match_lines_rev(pattern).next() - except StopIteration, e: - # force invalid line number - self.cur_line_num = None - return None - self.cur_line_num = len(self.lines) - 1 - return self.cur_line - def insert (self, s=''): - """This inserts the string as a new line before the current line number. - """ - self.lines.insert(self.cur_line_num, s) - def append (self, s=''): - """Unlike list append, this appends after the current line number, - not at the end of the entire list. - """ - self.cur_line_num = self.cur_line_num + 1 - self.lines.insert(self.cur_line_num, s) - def delete (self): - del self.cur_line - def read (self, file_holder): - """This reads all the lines from a file. The file_holder may be - either a string filename or any object that supports "read()". - All previous lines are lost. - """ - if hasattr(file_holder, 'read') and callable(file_holder.read): - fin = file_holder - else: - fin = open (file_holder, 'rb') - data = fin.read() - self.lines = data.splitlines() - self.cur_line_num = 0 - def write (self, file_holder): - """This writes all the lines to a file. The file_holder may be - either a string filename or any object that supports "read()". - TODO: Make write be atomic using file move instead of overwrite. - """ - if hasattr(file_holder, 'write') and callable(file_holder.write): - fout = file_holder - else: - fout = open (file_holder, 'wb') - for l in self.lines: - fout.write(l) - fout.write('\n') - # the following are for smart properties. - def __str__ (self): - return '\n'.join(self.lines) - def __get_cur_line (self): - self.__cur_line = self.lines[self.cur_line_num] - return self.__cur_line - def __set_cur_line (self, value): - self.__cur_line = value - self.lines[self.cur_line_num] = self.__cur_line - def __del_cur_line (self): - del self.lines[self.cur_line_num] - if self.cur_line_num >= len(self.lines): - self.cur_line_num = len(self.lines) - 1 - cur_line = property (__get_cur_line, __set_cur_line, __del_cur_line) - # lines = property (get_lines, set_lines, del_lines) - -__NOT_USED =""" -import sys -pe = pyed() -pe.read(sys.stdin) -#print "---" -#print list(x.cur_line for x in pe.match_lines_rev('^#')) -#print pe.first('^#') -#print pe.last('^#') -#print "---" -for pe in pe.match_lines('^\\s*#'): - pe.cur_line = pe.cur_line.lower() -pe.last('# comment.*') -pe.cur_line = '# Comment 1' -print pe -if pe.last('asdfasdf') is None: - print "can't find 'asdfasdf'" -""" - diff --git a/pexpect/tools/sfupload.py b/pexpect/tools/sfupload.py deleted file mode 100755 index 8a3b078..0000000 --- a/pexpect/tools/sfupload.py +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env python -'''This uploads the latest pexpect package to sourceforge. - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' -import pexpect -import sys - -child = pexpect.spawn('ftp upload.sourceforge.net') -child.logfile = sys.stdout -child.expect('Name .*: ') -child.sendline('anonymous') -child.expect('Password:') -child.sendline('noah@noah.org') -child.expect('ftp> ') -child.sendline('cd /incoming') -child.expect('ftp> ') -child.sendline('lcd dist') -child.expect('ftp> ') -child.sendline('bin') -child.expect('ftp> ') -child.sendline('prompt') -child.expect('ftp> ') -child.sendline('mput pexpect-*.tar.gz') -child.expect('ftp> ') -child.sendline('ls pexpect*') -child.expect('ftp> ') -print child.before -child.sendline('bye') - diff --git a/pexpect/tools/step.py b/pexpect/tools/step.py deleted file mode 100755 index cc0062e..0000000 --- a/pexpect/tools/step.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python -''' -# This single steps through a log file. - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import tty, termios, sys - -def getkey(): - file = sys.stdin.fileno() - mode = termios.tcgetattr(file) - try: - tty.setraw(file, termios.TCSANOW) - ch = sys.stdin.read(1) - finally: - termios.tcsetattr(file, termios.TCSANOW, mode) - return ch - -fin = open ('log', 'rb') -fout = open ('log2', 'wb') - -while 1: - foo = fin.read(1) - if foo == '': - sys.exit(0) - sys.stdout.write(foo) - getkey() - fout.write (foo) - fout.flush() - diff --git a/pexpect/tools/testall.py b/pexpect/tools/testall.py deleted file mode 100755 index 28307c7..0000000 --- a/pexpect/tools/testall.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env python -'''This script runs all tests in a directory. -It does not need to know about the tests ahead of time. -It recursively descends from the current directory and -automatically builds up a list of tests to run. -Only directories named 'tests' are processed. -The path to each 'tests' directory is added to the PYTHONPATH. -Only python scripts that start with 'test_' are added to -the list of scripts in the test suite. -Noah Spurrier - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import unittest -import os, os.path -import sys - -import pexpect -print "Testing pexpect version:", pexpect.__version__ -print "Testing pexpect revision:", pexpect.__revision__ - -def add_tests_to_list (import_list, dirname, names): - # Only check directories named 'tests'. - if os.path.basename(dirname) != 'tests': - return - # Add any files that start with 'test_' and end with '.py'. - for f in names: - filename, ext = os.path.splitext(f) - if ext != '.py': - continue - if filename.find('test_') == 0: - import_list.append (os.path.join(dirname, filename)) - -def find_modules_and_add_paths (root_path): - import_list = [] - module_list = [] - os.path.walk (root_path, add_tests_to_list, import_list) - for module_file in import_list: - path, module = os.path.split(module_file) - module_list.append (module) - print 'Adding:', module_file - if not path in sys.path: - sys.path.append (path) - if not os.path.dirname(path) in sys.path: - sys.path.append (os.path.dirname(path)) - module_list.sort() - return module_list - -def suite(): - modules_to_test = find_modules_and_add_paths (os.getcwd()) - alltests = unittest.TestSuite() - for module in map(__import__, modules_to_test): - alltests.addTest(unittest.findTestCases(module)) - return alltests - -if __name__ == '__main__': - unittest.main(defaultTest='suite') -# s = all() -# runner = unittest.TextTestRunner() -# runner.run (s) - diff --git a/pexpect/tools/testsweep.py b/pexpect/tools/testsweep.py deleted file mode 100755 index 0f2c4d5..0000000 --- a/pexpect/tools/testsweep.py +++ /dev/null @@ -1,72 +0,0 @@ -#!/usr/bin/env python -"""This runs testall.py on many different platforms running on the Compile Farm (cf.sourceforge.net). - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -""" -import pexpect -import sys -import getpass - -def test_platform (platform_menu, platform_python_path): - try: - s = pexpect.spawn ('ssh noah@cf.sourceforge.net') - #s.setlog (sys.stdout) - i = s.expect (['password:', 'yes/no']) - if i == 1: - s.sendline ('yes') - s.expect ('password') - s.sendline (PASSWORD) - s.expect ('Choose compile farm server') - s.sendline (platform_menu) - s.expect_exact ('$') - s.sendline ('cd pexpect') - s.expect_exact ('$') - s.sendline ('. ./cvs.conf') - s.expect_exact ('$') - s.sendline ('cvs up -d') - s.expect ('password:') - s.sendline (PASSWORD) - s.expect_exact ('$') - s.sendline (platform_python_path) - i = s.expect_exact (['OK','$'], timeout=900) # Tests should not run more than 15 minutes. - if i != 0: - RESULT = s.before - else: - RESULT = 'OK!' - s.sendline ('exit') - s.sendline ('x') - s.close() - except Exception, e: - return 'Exception in platform test: ' + str(e) - return RESULT - -PASSWORD = getpass.getpass('password: ') -results = [] -result = test_platform ('I', 'python tools/testall.py') -results.append (('I', '[PPC - G4] MacOS X 10.1 SERVER Edition', result)) -result = test_platform ('L', 'python tools/testall.py') -results.append (('L', '[Sparc - Ultra60] Linux 2.4 (Debian 3.0)', result)) -result = test_platform ('B', 'python2 tools/testall.py') -results.append (('B', '[x86] Linux 2.4 (Redhat 7.3)', result)) -result = test_platform ('M', '../Python-2.3b1/python tools/testall.py') -results.append (('M', '[Sparc - R220] Sun Solaris (8) #1', result)) -result = test_platform ('G', 'python tools/testall.py') -results.append (('G', '[Alpha] Linux 2.2 (Debian 3.0)', result)) -print results - diff --git a/pexpect/tools/tweak_files.py b/pexpect/tools/tweak_files.py deleted file mode 100755 index 4ab8b22..0000000 --- a/pexpect/tools/tweak_files.py +++ /dev/null @@ -1,45 +0,0 @@ -''' - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import pyed -import sys, os, re - -# extract the version number from the pexpect.py source. -d = pyed.pyed() -d.read ("pexpect.py") -d.first('^__version__') -r = re.search("'([0-9]\.[0-9])'", d.cur_line) -version = r.group(1) - -# Edit the index.html to update current VERSION. -d = pyed.pyed() -d.read ("doc/index.html.template") -for cl in d.match_lines('.*VERSION.*'): - d.cur_line = d.cur_line.replace('VERSION', version) -d.write("doc/index.html") - -# Edit the setup.py to update current VERSION. -d = pyed.pyed() -d.read ("setup.py.template") -for cl in d.match_lines('.*VERSION.*'): - d.cur_line = d.cur_line.replace('VERSION', version) -d.write("setup.py") -os.chmod("setup.py", 0755) diff --git a/pexpect/tools/websync.py b/pexpect/tools/websync.py deleted file mode 100755 index a4ee141..0000000 --- a/pexpect/tools/websync.py +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python - -''' -I used to use this to keep the sourceforge pages up to date with the -latest documentation and I like to keep a copy of the distribution -on the web site so that it will be compatible with -The Vaults of Parnasus which requires a direct URL link to a -tar ball distribution. I don't advertise the package this way. - -PEXPECT LICENSE - - This license is approved by the OSI and FSF as GPL-compatible. - http://opensource.org/licenses/isc-license.txt - - Copyright (c) 2012, Noah Spurrier <noah@noah.org> - PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY - PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE - COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES. - THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -''' - -import pexpect, pyed -import getpass -import sys, os - -X = getpass.getpass('Password: ') -pp_pattern=["(?i)password:", "(?i)enter passphrase for key '.*?':"] - -p = pexpect.spawn ('scp -r doc/. noah@shell.sourceforge.net:/home/groups/p/pe/pexpect/htdocs/.') -p.logfile_read = sys.stdout -p.expect (pp_pattern) -p.sendline (X) -p.expect (pexpect.EOF) -print p.before - -p = pexpect.spawn ('scp doc/clean.css doc/email.png noah@shell.sourceforge.net:/home/groups/p/pe/pexpect/htdocs/clean.css') -p.logfile_read = sys.stdout -p.expect (pp_pattern) -p.sendline (X) -p.expect (pexpect.EOF) -print p.before - -#p = pexpect.spawn ('ssh noah@use-pr-shell1.sourceforge.net "cd htdocs;tar zxvf pexpect-doc.tgz"') -#p.logfile_read = sys.stdout -#p.expect ('password:') -#p.sendline (X) -#p.expect (pexpect.EOF) -#print p.before - -p = pexpect.spawn ('scp dist/pexpect-*.tar.gz noah@shell.sourceforge.net:/home/groups/p/pe/pexpect/htdocs/.') -p.logfile_read = sys.stdout -p.expect (pp_pattern) -p.sendline (X) -p.expect (pexpect.EOF) -print p.before - |