forked from OSchip/llvm-project
116 lines
3.0 KiB
Python
116 lines
3.0 KiB
Python
#!/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
|
|
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import time
|
|
import getopt
|
|
import signal
|
|
import fcntl
|
|
import termios
|
|
import 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 as 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 as e:
|
|
raise e
|
|
except Exception as e:
|
|
print "ERROR"
|
|
print str(e)
|
|
traceback.print_exc()
|
|
os._exit(1)
|