shlex 2.16 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
#!/usr/bin/env python3
"""
	shlex - execve but apply shlex to argv
"""
import shlex
import subprocess
import logging
import os
import sys
import argparse
11
import shutil
12
13
14
15

LOGGER = logging.getLogger(os.path.basename(__file__))

ARGP = argparse.ArgumentParser()
16
17
ARGP.add_argument('--subprocess-shell', '-S', action='store_true')
ARGP.add_argument('--verbose', '-v', action='store_true')
dylan grafmyre's avatar
dylan grafmyre committed
18
19
ARGP.add_argument('--tail-bin')
ARGP.add_argument('--tail', help="follow a file while supervising a subprocess")
20
21
22
23
24
ARGP.add_argument('remainder', nargs=argparse.REMAINDER)

def main(argp=None, argv=None):
    if argp is None:
        argp = ARGP.parse_args(argv)
25
26
27
    logging.basicConfig(
        level=(logging.INFO if argp.verbose else logging.WARNING),
    )
28
29
30
31
32
33
34
35
36

    LOGGER.info('execve_orig: %r', argp.remainder)
    execve = shlex.split(' '.join(argp.remainder))  #  + ['&', 'exit']  windows hack to get returncode?
    LOGGER.info('execve_shlex: %r', execve)
    execve = [
        (os.path.normpath(i) if os.path.isfile(i) else i)
        for i in execve
    ]
    LOGGER.info('execve_shlex_normpath: %r', execve)
37
38
39
40
41
42
43
44
45
46
47

    bin_ = execve[0]
    #if not os.path.isfile(bin_):
    #    LOGGER.error('os path is not file: %r', bin_)
    which_bin = shutil.which(bin_)
    if which_bin is not None and which_bin != bin_:
        LOGGER.error('execve[0]: %r -> %r', bin_, which_bin)
        execve[0] = which_bin

    LOGGER.info('execve: %r', execve)
    LOGGER.info('execve_shell: %r', argp.subprocess_shell)
dylan grafmyre's avatar
dylan grafmyre committed
48
49
50
51
52
53
54
55
56
    tail_popen = None
    if argp.tail:
        if not argp.tail_bin:
            raise RuntimeError('--tail-bin is required')
        if 'CPROGRAMFILESOLD' in argp.tail:
            argp.tail = argp.tail.replace('CPROGRAMFILESOLD', 'C:\\program files (x86)')
        if 'CPROGRAMFILES' in argp.tail_bin:
            argp.tail_bin = argp.tail_bin.replace('CPROGRAMFILES', 'C:\\program files')
        tail_popen = subprocess.Popen([argp.tail_bin, '-fn0', argp.tail], stdout=sys.stderr.buffer)
57
    cproc = subprocess.run(execve, shell=argp.subprocess_shell)
dylan grafmyre's avatar
dylan grafmyre committed
58
59
    if tail_popen:
        tail_popen.kill()
60
61
62
63
64
    LOGGER.info('execve_rc: %r', cproc.returncode)
    return cproc.returncode

if __name__ == '__main__':
	exit(main())