bash-color-grc/grc

202 lines
5.1 KiB
Plaintext
Raw Permalink Normal View History

2016-08-28 19:17:53 +02:00
#! /usr/bin/env python3
2015-01-25 18:36:02 +01:00
from __future__ import print_function
2016-08-28 19:17:53 +02:00
import os, re, string, sys, getopt, signal
2015-01-25 18:36:02 +01:00
def version():
2021-07-26 18:11:58 +02:00
print ("Generic Colouriser 1.13")
2015-01-25 18:36:02 +01:00
sys.exit()
def help():
2021-07-26 18:11:58 +02:00
print("""Generic Colouriser 1.13
2015-01-25 18:36:02 +01:00
grc [options] command [args]
2017-02-09 14:33:16 +01:00
Options:
2015-01-25 18:36:02 +01:00
-e --stderr redirect stderr. If this option is selected,
do not automatically redirect stdout
-s --stdout redirect stdout, even if -e is selected
-c name --config=name use name as configuration file for grcat
--colour=word word is one of: on, off, auto
2016-08-28 19:20:46 +02:00
--pty run command in pseudoterminal (experimental)
2015-01-25 18:36:02 +01:00
""")
sys.exit()
def catch_signal(signum, frame):
"catch signal sent to grc and forward it to the original application"
global pidp
try:
os.kill(pidp, signum)
except OSError: # if the subprocess already died
pass
try:
2016-08-28 19:20:46 +02:00
optlist, args = getopt.getopt(sys.argv[1:], "sec:", ["stdout", "stderr", "config=", "colour=", "pty"] )
2015-01-25 18:36:02 +01:00
except:
help()
if not args:
help()
stdoutf = 0
stderrf = 0
# configure file for grcat
cfile = ""
2018-04-29 10:05:34 +02:00
colour = sys.stdout.isatty()
2016-08-28 19:20:46 +02:00
use_pty = 0
2015-01-25 18:36:02 +01:00
for i in optlist:
if i[0] in ["--stderr", "-e"]:
2016-07-31 15:34:41 +02:00
# redirect stderr
2015-01-25 18:36:02 +01:00
stderrf = 1
elif i[0] in ["--stdout", "-s"]:
2016-07-31 15:34:41 +02:00
# redirect stdout
2015-01-25 18:36:02 +01:00
stdoutf = 1
elif i[0] in ["--config", "-c"]:
cfile = i[1]
elif i[0] == "--colour":
if i[1] == "on":
colour = 1
elif i[1] == "off":
colour = 0
elif i[1] == "auto":
colour = sys.stdout.isatty()
else:
help()
2016-08-28 19:20:46 +02:00
elif i[0] == '--pty':
use_pty = 1
2015-01-25 18:36:02 +01:00
stdoutff = 1
stderrff = 0
if stderrf == 1:
stdoutff = 0
stderrff = 1
if stdoutf == 1:
stdoutff = 1
2016-08-28 19:20:46 +02:00
if use_pty:
import pty
2015-01-25 18:36:02 +01:00
if cfile == "":
home = os.environ.get('HOME')
xdg = os.environ.get('XDG_CONFIG_HOME')
if not xdg and home:
xdg = home + '/.config'
conffilenames = ['/etc/grc.conf', '/usr/local/etc/grc.conf']
if xdg:
conffilenames += [xdg + '/grc/grc.conf']
if home:
conffilenames += [home + '/.grc/grc.conf']
for conffile in conffilenames:
2016-12-14 14:53:36 +01:00
# test if conffile exists, it can be also a pipe
if os.path.exists(conffile) and not os.path.isdir(conffile):
f = open(conffile, "r")
while 1:
l = f.readline()
if l == "":
break
if l[0] == "#" or l[0] == '\012':
continue
regexp = l.strip()
if re.search(regexp, ' '.join(args)):
cfile = f.readline().strip()
break
2015-01-25 18:36:02 +01:00
signal.signal(signal.SIGINT, catch_signal)
if cfile != "" and colour:
if stdoutff:
choo, chio = os.pipe()
if stderrff:
choe, chie = os.pipe()
2016-08-28 19:17:53 +02:00
if use_pty:
pidp, pty_fd = pty.fork()
else:
pidp = os.fork()
2016-08-28 20:51:20 +02:00
if pidp == 0: # child, command to run
2015-01-25 18:36:02 +01:00
if stdoutff:
2016-07-31 15:34:41 +02:00
# connect child (this) stdout to pipe write end
2016-08-28 19:17:53 +02:00
if not use_pty:
os.dup2(chio, 1)
os.close(choo)
os.close(chio)
2015-01-25 18:36:02 +01:00
if stderrff:
2016-08-28 19:17:53 +02:00
os.dup2(chie, 2)
os.close(choe)
os.close(chie)
try:
os.execvp(args[0], args)
except OSError as e:
sys.stderr.write('grc: %s: %s\n' % (args[0], e.strerror))
sys.exit(1)
2016-08-28 19:17:53 +02:00
2015-01-25 18:36:02 +01:00
if stdoutff:
pido = os.fork()
2016-08-28 20:51:20 +02:00
if pido == 0: # child, grcat
# connect grcat's stdin to pipe read end, or pty master
2016-08-28 19:17:53 +02:00
if use_pty:
os.dup2(pty_fd, 0)
else:
os.dup2(choo, 0)
2015-01-25 18:36:02 +01:00
os.close(choo)
os.close(chio)
if stderrff:
os.close(choe)
os.close(chie)
os.execvp("grcat", ["grcat", cfile])
if stderrff:
pide = os.fork()
if pide == 0: # child
os.dup2(choe, 0)
os.dup2(2, 1)
os.close(choe)
os.close(chie)
if stdoutff:
os.close(choo)
os.close(chio)
os.execvp("grcat", ["grcat", cfile])
try:
status = os.waitpid(pidp, 0)[1]
except OSError: # interrupted system call
status = None
pass # this is probably not correct
2016-10-17 20:47:57 +02:00
# except KeyboardInterrupt: # catching SIGINT does not work when using pty...
# status = None
# os.kill(pidp, signal.SIGINT)
# pass
2015-01-25 18:36:02 +01:00
if stderrff:
os.close(chie)
os.waitpid(pide, 0)
os.close(choe)
if stdoutff:
os.close(chio)
os.waitpid(pido, 0)
os.close(choo)
sys.exit(status and os.WEXITSTATUS(status))
else:
2016-07-31 15:34:41 +02:00
pidp = os.fork()
2015-01-25 18:36:02 +01:00
if pidp == 0:
try:
os.execvp(args[0], args)
except OSError as e:
sys.stderr.write('grc: %s: %s\n' % (args[0], e.strerror))
sys.exit(1)
2015-01-25 18:36:02 +01:00
try:
status = os.wait()[1]
except OSError: # interrupted system call
status = None
pass # this is probably not correct
sys.exit(status and os.WEXITSTATUS(status))