Home | History | Annotate | Download | only in examples
      1 #!/usr/bin/env python
      2 
      3 """This spawns a sub-shell (bash) and gives the user interactive control. The
      4 entire shell session is logged to a file called script.log. This behaves much
      5 like the classic BSD command 'script'.
      6 
      7 ./script.py [-a] [-c command] {logfilename}
      8 
      9     logfilename : This is the name of the log file. Default is script.log.
     10     -a : Append to log file. Default is to overwrite log file.
     11     -c : spawn command. Default is to spawn the sh shell.
     12 
     13 Example:
     14 
     15     This will start a bash shell and append to the log named my_session.log:
     16 
     17         ./script.py -a -c bash my_session.log
     18 
     19 """
     20 
     21 import os, sys, time, getopt
     22 import signal, fcntl, termios, struct
     23 import traceback
     24 import pexpect
     25 
     26 global_pexpect_instance = None # Used by signal handler
     27 
     28 def exit_with_usage():
     29 
     30     print globals()['__doc__']
     31     os._exit(1)
     32 
     33 def main():
     34 
     35     ######################################################################
     36     # Parse the options, arguments, get ready, etc.
     37     ######################################################################
     38     try:
     39         optlist, args = getopt.getopt(sys.argv[1:], 'h?ac:', ['help','h','?'])
     40     except Exception, e:
     41         print str(e)
     42         exit_with_usage()
     43     options = dict(optlist)
     44     if len(args) > 1:
     45         exit_with_usage()
     46         
     47     if [elem for elem in options if elem in ['-h','--h','-?','--?','--help']]:
     48         print "Help:"
     49         exit_with_usage()
     50 
     51     if len(args) == 1:
     52         script_filename = args[0]
     53     else:
     54         script_filename = "script.log"
     55     if '-a' in options:
     56         fout = file (script_filename, "ab")
     57     else:
     58         fout = file (script_filename, "wb")
     59     if '-c' in options:
     60         command = options['-c']
     61     else:
     62         command = "sh"
     63 
     64     # Begin log with date/time in the form CCCCyymm.hhmmss
     65     fout.write ('# %4d%02d%02d.%02d%02d%02d \n' % time.localtime()[:-3])
     66     
     67     ######################################################################
     68     # Start the interactive session
     69     ######################################################################
     70     p = pexpect.spawn(command)
     71     p.logfile = fout
     72     global global_pexpect_instance
     73     global_pexpect_instance = p
     74     signal.signal(signal.SIGWINCH, sigwinch_passthrough)
     75 
     76     print "Script recording started. Type ^] (ASCII 29) to escape from the script shell."
     77     p.interact(chr(29))
     78     fout.close()
     79     return 0
     80 
     81 def sigwinch_passthrough (sig, data):
     82 
     83     # Check for buggy platforms (see pexpect.setwinsize()).
     84     if 'TIOCGWINSZ' in dir(termios):
     85         TIOCGWINSZ = termios.TIOCGWINSZ
     86     else:
     87         TIOCGWINSZ = 1074295912 # assume
     88     s = struct.pack ("HHHH", 0, 0, 0, 0)
     89     a = struct.unpack ('HHHH', fcntl.ioctl(sys.stdout.fileno(), TIOCGWINSZ , s))
     90     global global_pexpect_instance
     91     global_pexpect_instance.setwinsize(a[0],a[1])
     92 
     93 if __name__ == "__main__":
     94     try:
     95         main()
     96     except SystemExit, e:
     97         raise e
     98     except Exception, e:
     99         print "ERROR"
    100         print str(e)
    101         traceback.print_exc()
    102         os._exit(1)
    103 
    104