public
Last active

  • Download Gist
screenutils.py
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
#!/usr/bin/env python
# -*- coding:utf-8 -*-
#
# Now this lib is on her own full repository and pypi page:
# http://github.com/Christophe31/screenutils
# http://pypi.python.org/pypi/screenutils
#
# This may not work with bpython, use python 2.6 or upper
#
# This program is free software. It comes without any warranty, to
# the extent permitted by applicable law. You can redistribute it
# and/or modify it under the terms of the GNU Public License 2 or upper.
# Please ask if you wish a more permissive license.
#
# Author: Christophe Narbonne
# Contrib: Alexis Metaireau
from commands import getoutput
from multiprocessing import Process
from os import system
from time import sleep
 
 
def list_screens():
"""List all the existing screens and build a Screen instance for each
"""
return [Screen(".".join(l.split(".")[1:]).split("\t")[0])
for l in getoutput("screen -ls | grep -P '\t'").split('\n')]
 
 
class ScreenNotFoundError(Exception):
"""raised when the screen does not exists"""
 
 
class Screen(object):
"""Represents a gnu-screen object::
 
>>> s=Screen("screenName", create=True)
>>> s.name
'screenName'
>>> s.exists
True
>>> s.state
>>> s.send_commands("man -k keyboard")
>>> s.kill()
>>> s.exists
False
"""
 
def __init__(self, name, create=False):
self.name = name
self._id = None
self._status = None
if create:
self.create()
 
@property
def id(self):
"""return the identifier of the screen as string"""
if not self._id:
self._set_screen_infos()
return self._id
 
@property
def status(self):
"""return the status of the screen as string"""
self._set_screen_infos()
return self._status
 
@property
def exists(self):
"""Tell if the screen session exists or not."""
# output line sample:
# " 28062.G.Terminal (Detached)"
lines = getoutput("screen -ls | grep " + self.name).split('\n')
return self.name in [".".join(l.split(".")[1:]).split("\t")[0]
for l in lines]
 
def create(self):
"""create a screen, if does not exists yet"""
if not self.exists:
Process(target=self._delayed_detach).start()
system('screen -UR ' + self.name)
 
def interrupt(self):
"""Insert CTRL+C in the screen session"""
self._check_exists()
system("screen -x " + self.name + " -X eval \"stuff \\003\"")
 
def kill(self):
"""Kill the screen applications then quit the screen"""
self._check_exists()
system('screen -x ' + self.name + ' -X quit')
 
def detach(self):
"""detach the screen"""
self._check_exists()
system("screen -d " + self.name)
 
def _delayed_detach(self):
sleep(5)
self.detach()
 
def send_commands(self, *commands):
"""send commands to the active gnu-screen"""
self._check_exists()
for command in commands:
sleep(0.02)
system('screen -x ' + self.name + ' -X stuff "' + command + '" ')
sleep(0.02)
system('screen -x ' + self.name + ' -X eval "stuff \\015" ')
 
def _check_exists(self, message="Error code: 404"):
"""check whereas the screen exist. if not, raise an exception"""
if not self.exists:
raise ScreenNotFoundError(message)
 
def _set_screen_infos(self):
"""set the screen information related parameters"""
if self.exists:
infos = getoutput("screen -ls | grep %s" % self.name).split('\t')[1:]
self._id = infos[0].split('.')[0]
self._date = infos[1][1:-1]
self._status = infos[2][1:-1]
 
def __repr__(self):
return "<%s '%s'>" % (self.__class__.__name__, self.name)

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.