-
-
Notifications
You must be signed in to change notification settings - Fork 6
/
pysh.py
84 lines (71 loc) · 2.81 KB
/
pysh.py
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
#!/usr/bin/python
import os
import argparse
import tempfile
from contextlib import redirect_stdout
parser = argparse.ArgumentParser(description="Run python-enhanced bash scripts")
parser.add_argument("script", action="store",
help="filename of python-enhanced bash script")
parser.add_argument("-d", "--debug", action="store_true",
help="Only show the generated bash script, without execution")
args = parser.parse_args()
script = args.script
shell = "/bin/bash"
# Divide the input script into 'bash' and 'python' blocks.
blocks = []
block = []
lastType = "bash"
with open(script) as fIn:
for line in fIn.readlines():
if line.strip().startswith("#> "):
lineType = "python"
else:
lineType = "bash"
if lineType == lastType:
block.append(line)
else:
# block ends here
blocks.append((lastType, block))
# start new block
block = [line]
lastType = lineType
# append last block
blocks.append((lineType, block))
# Create a temporary file for exchanging variable from python back to bash
envFile = tempfile.NamedTemporaryFile("wt", delete=False)
envFile.close()
with tempfile.NamedTemporaryFile("wt", delete=False) as outFile:
with redirect_stdout(outFile):
print("#!{shell}".format(shell=shell))
print("set -o allexport")
print("")
for bType, lines in blocks:
if bType == "python":
print("python <<EOF")
print("import os")
print("import sys")
print("for k, v in os.environ.items():")
print(" locals()[k] = v")
print("")
lines = [line.strip()[3:].replace("$", "\\$") for line in lines]
print("\n".join(lines))
print("pyEnv = {k: v for k, v in locals().items()}")
print("")
print('with open("{envFile}", "w") as f:'.format(envFile=envFile.name))
print(" for k, v in pyEnv.items():")
print(" if 'BASH_FUNC' in k:")
print(" continue")
print(" if type(v) in [str, int, float, bool]:")
print(" val = str(v).replace('\"', '\\\\\\\"')")
print(" val = val.replace('$', '\\\\$')")
print(" f.write('{k}=\"{val}\"\\n'.format(k=k, val=val))")
print("EOF")
print("source '{envFile}'".format(envFile=envFile.name))
else:
print("".join(lines))
if args.debug:
os.system("cat '{script}'".format(script=outFile.name))
else:
os.system("{shell} '{script}'".format(shell=shell, script=outFile.name))
os.remove(outFile.name)
os.remove(envFile.name)