Nov-25-2017, 08:32 AM
file session.py is a command i created to start background screen sessions set to the same terminal geometry as started from, if available, or a specified geometry, that can be specified in many ways. a session name is the only required argument. the columns, rows, and starting command are optional. the name, columns, and rows can be given inline as plain numbers, or assigned as keyed options in many ways, and abbreviated all the way down to one letter. when given as plain numbers where the order does not matter, it determines which is columns and which is rows by alays havin the number of columns be the larger number. when using keyed options, the values can be specifically assigned. if no command string is given then the new session is stuffed with a comment indicating when the session was created. here are examples:
session 160 50 foo ping 8.8.4.4
start a screen session named "foo" with a virtual 160x80 terminal on a shell running a ping command to ping one of Google's generic DNS servers.
session 50 bar 160
start a screen session named "bar" with a virtual 160x80 terminal on a shell sitting idle with a command line comment stating when the session was started.
session co=80 ro=96 xyzzy
start a screen session named "xyzzy" with a virtual 80x96 terminal on a shell sitting idle with a command line comment stating when the session was started.
session //row 72 test1 64 ping localhost
start a screen session named "test1" with a virtual 64x72 terminal on a shell running a ping of localhost. a message will be output indicating that since one number was explicitely specified as rows, the other number is assumed to be columns.
session 160 50 foo ping 8.8.4.4
start a screen session named "foo" with a virtual 160x80 terminal on a shell running a ping command to ping one of Google's generic DNS servers.
session 50 bar 160
start a screen session named "bar" with a virtual 160x80 terminal on a shell sitting idle with a command line comment stating when the session was started.
session co=80 ro=96 xyzzy
start a screen session named "xyzzy" with a virtual 80x96 terminal on a shell sitting idle with a command line comment stating when the session was started.
session //row 72 test1 64 ping localhost
start a screen session named "test1" with a virtual 64x72 terminal on a shell running a ping of localhost. a message will be output indicating that since one number was explicitely specified as rows, the other number is assumed to be columns.
#!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import division, generators, print_function, with_statement """Create screen sessions with a specified name and optionally a specified width and height. file session.py purpose create screen sessions with a specified name and optionally a specified width and height method command syntax session <options> [ <session_input> ] options name (required), cols (optional), rows (optional) option forms {,-,+,*,/,--,++,**,//}name=<name> {,-,+,*,/,--,++,**,//}nam=<name> {,-,+,*,/,--,++,**,//}na=<name> {,-,+,*,/,--,++,**,//}n=<name> {-,+,*,/,--,++,**,//}name <name> {-,+,*,/,--,++,**,//}nam <name> {-,+,*,/,--,++,**,//}na <name> {-,+,*,/,--,++,**,//}n <name> cols and rows may also be specified in like forms name, cols and rows values may also be specified alone email 10054452614123394844460370234029112340408691 The intent is that this module and command works correctly under both Python 2 and Python 3. Please report failures or code improvement to the author. """ __license__ = """ Copyright © 2017, by Phil D. Howard - all other rights reserved 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. The author may be contacted by decoding the number 10054452614123394844460370234029112340408691 (provu igi la numeron al duuma) """ # source code configuration: howto_detach = chr(29)+'d' import os,fcntl,struct,termios from os import environ from sys import argv, stderr, stdin, stdout, version_info from subprocess import call from time import localtime, sleep, strftime, time as secs bases = { -8, -1, 0, 1, 2, 3, 4, 8, 10, 16, 32, 36 } octal = {'','0','1','2','3','4','5','6','7'} datef = '%Y-%m-%d %H:%M:%S' #-------#-------#-------#-------#-------#-------#-------#-------#-------#-------# exitcode = 0 def error(*args): global exitcode if not args: return 1 if exitcode < args[0]: exitcode = args[0] print(*(args[1:]),file=stderr) return 1 #-------#-------#-------#-------#-------#-------#-------#-------#-------#-------# def geo(fd=1): try: h,w = struct.unpack('4H',fcntl.ioctl(fd,termios.TIOCGWINSZ,struct.pack('4H',0,0,0,0)))[:2] except: h,w = None,None if not h: try: fd = os.open('/dev/tty',os.O_WRONLY) h,w = struct.unpack('4H',fcntl.ioctl(fd,termios.TIOCGWINSZ,struct.pack('4H',0,0,0,0)))[:2] os.close(fd) except: h,w = None,None return w,h #-------#-------#-------#-------#-------#-------#-------#-------#-------#-------# def intx(*a): "Convert digits to int, in an extended way, better than int()" b = bases if len(a) > 1: b = set(a[1]) # i bet you do not understand this: d = a[0].lower() if bytes == str: d = ''.join([chr(c) for c in bytearray(d)]) elif isinstance(d,(bytes,bytearray)): d = ''.join([chr(c) for c in bytearray(d)]) if 0 in b: try: return intx(d,b-{0}) except ValueError: return None if -1 in b and d[:1]=='-': return -intx(d[:1],b-{-1}) if -2 in b: return -intx(d,b-{-2}) # the order of the next 7 does not matter, # but is arranged in order of probability if 16 in b: if d[:2]=='0x': return int(d[2:],16) if d[:1]=='x': return int(d[1:],16) if 8 in b: if d[:2]=='0o': return int(d[2:],8) if d[:1]=='o': return int(d[1:],8) if 2 in b: if d[:2]=='0b': return int(d[2:],2) if d[:1]=='b': return int(d[1:],2) if 3 in b: if d[:2]=='0t': return int(d[2:],3) if d[:1]=='t': return int(d[1:],3) if 4 in b: if d[:2]=='0q': return int(d[2:],4) if d[:1]=='q': return int(d[1:],4) if 32 in b: if d[:2]=='0y': return int(d[2:],32) if d[:1]=='y': return int(d[1:],32) if 36 in b: if d[:1]==':': return int(d[1:],36) if -8 in b: if d[:1]=='0': if d[1:2] in octal: return int(d[1:],8) if 10 in b: return int(d,10) return None #-------#-------#-------#-------#-------#-------#-------#-------#-------#-------# def main(args): errors = 0 optm = {} for o in ('cols','rows','name'): for n in range(1,len(o)+1): optm[o[0:n]] = o cmd_name = args.pop(0) optd = {} namz = numz = while args: arg = args.pop(0) if not arg: errors += error(1,'empty argument',repr(arg)) elif arg[0:2] in {'--','++','**','//'}: opt = arg[2:] if '=' in opt: opt, val = opt.split('=',1) else: if not args: errors += error(1,'no argument for',repr(arg)) val = args.pop(0) if opt in optm: optd[optm[opt.lower()]] = val else: errors += error(1,' Unknown assignment option name in',repr(arg)) elif arg[0:1] in {'-','+','*','/'}: opt = arg[1:] if '=' in opt: opt, val = opt.split('=',1) else: if not args: errors += error(1,'no argument for',repr(arg)) val = args.pop(0) if opt in optm: optd[optm[opt.lower()]] = val else: errors += error(1,'Unknown assignment option name in',repr(arg)) elif '=' in arg: opt, val = arg.split('=',1) if opt in optm: optd[optm[opt.lower()]] = val else: errors += error(1,'unknown assignment option name in',repr(arg)) else: num = intx(arg) if isinstance(num,int): numz.append(num) else: if len(namz) > 0: args = [ arg ] + args break namz.append(arg) while True: if args: stuff_in = ' '.join(args) else: stuff_in = '# this screen session was started at {} by the {} commamd'.format(strftime(datef,localtime(secs())),repr(cmd_name)) if 'name' in optd: namz.append(optd.pop('name')) if len(namz) < 1: errors += error(1,'no name given') if len(namz) > 1: errors += error(1,'internal logic error - more than one name - ',repr(namz)) name = namz[0] if len(numz) == 0: if 'cols' not in optd or 'rows' not in optd: cols, rows = geo() if cols is None or rows is None: errors += error(1,'cols and rows not specified and current geometry not available') optd['cols'], optd['rows'] = cols, rows break if len(numz) == 1: if 'cols' in optd and 'rows' in optd: errors += error(1,'more than two numbers specified - ',repr(numz)) break if 'cols' not in optd and 'rows' not in optd: errors += error(1,'just one number specified - unknown if it is cols or rows - ',repr(numz)) break if 'cols' in optd and 'rows' not in optd: print('cols specified so',numz[0],'presumed to be rows',file=stderr) optd['rows'] = numz[0] break if 'cols' not in optd and 'rows' in optd: print('rows specified so',numz[0],'presumed to be cols',file=stderr) optd['cols'] = numz[0] break if len(numz) == 2: cols, rows = numz if cols < rows: rows, cols = numz optd['cols'], optd['rows'] = cols, rows break if len(numz) > 2: errors += error(1,'more than two numbers specified - ',repr(numz)) break break cols, rows = str(optd.pop('cols')), str(optd.pop('rows')) for k,v in optd.items(): errors += error(1,'extra/unknown option specified',repr(k),'with value',repr(v)) if errors or exitcode: print('aborting ...',file=stderr) print(file=stderr) print('syntax:',cmd_name,'<name> [ <columns> <rows> [ <input> ... ] ]',file=stderr) print('or: ',cmd_name,'<name> [ <columns>x<rows> [ <input> ... ] ]',file=stderr) print('options: -cols -rows -name') return exitcode micro = int(secs()*1000000) # be sure the temp name can never begin with the real name tname = 'y'+str(micro)+name if name[0] == 'x' else 'x'+str(micro)+name bash_command = 'stty cols {} rows {};bash -i'.format(cols,rows) end_screen_1 = 'exit' +chr(13) new_screen_2 = 'screen -mDRR '+repr(name) +chr(13) environ['COLUMHS'] = environ['COLS'] = cols environ['LINES'] = environ['ROWS'] = rows call(['screen','-S',tname,'-dm','bash','-c',bash_command]) sleep(1) call(['screen','-S',tname,'-X','stuff',new_screen_2]) sleep(0.25) call(['screen','-S',tname,'-X','stuff',howto_detach]) sleep(0.25) call(['screen','-S',tname,'-X','stuff',end_screen_1]) sleep(0.5) call(['screen','-S',name,'-X','stuff',stuff_in+chr(13)]) return 0 #-------#-------#-------#-------#-------#-------#-------#-------#-------#-------# if __name__ == '__main__': if version_info.major < 3: BrokenPipeError = IOError try: result = main(argv) stdout.flush() except BrokenPipeError: result = 99 except KeyboardInterrupt: print('') result = 98 if result is 0 or result is None or result is True: exit(0) if result is 1 or result is False: exit(1) if isinstance(result,str): print(result,file=stderr) exit(2) try: exit(int(result)) except ValueError: print(str(result),file=stderr) exit(3) except TypeError: exit(4) #-------#-------#-------#-------#-------#-------#-------#-------#-------#-------# # 111111111122222222223333333333444444444455555555556666666666777777777788 #23456789012345678901234567890123456789012345678901234567890123456789012345678901 #=======#=======#=======#=======#=======#=======#=======#=======#=======#=======# # EOF
Tradition is peer pressure from dead people
What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.