1
2
3
4
5
6 import sys
7 import errno
8 import os
9 import signal
10
11 import libxyz.core as core
12
13 from libxyz.core.utils import bstring
14 from libxyz.core.plugins import BasePlugin
15
16 from bash import bash_setup
17
19 "Shell plugin"
20
21 NAME = u"shell"
22 AUTHOR = u"Max E. Kuznecov <syhpoon@syhpoon.name>"
23 VERSION = u"0.2"
24 BRIEF_DESCRIPTION = _(u"Shell wrapper")
25 FULL_DESCRIPTION = _(u"Execute commands in external shell")
26 NAMESPACE = u"core"
27 MIN_XYZ_VERSION = None
28 DOC = u"Configuration variables:\n"\
29 u"wait - Boolean flag indicating whether to wait for user pressing "\
30 u"key after command executed. Default True\n"\
31 u"setup_shell - Boolean flag indicating whether to run "\
32 u"system shell-specific initialization. Default True"
33
34 HOMEPAGE = "http://xyzcmd.syhpoon.name"
35 EVENTS = [("execute",
36 _(u"Fires before command execution. "\
37 u"Arguments: a command to be executed")),
38 ]
39
40 shell_args = {
41 "sh": ["-c"],
42 "bash": ["-c"],
43 "zsh": ["-c"]
44 }
45
46 shell_setup = {
47 "bash": bash_setup
48 }
49
58
59
60
74
75
76
78 """
79 Execute command in shell
80 """
81
82 cmd = bstring(cmd)
83 self.fire_event("execute", cmd)
84
85 def _exec():
86 pid = os.fork()
87
88
89 if pid == 0:
90 os.execvp(self.shell[0], self.shell + [cmd])
91
92 sys.exit()
93
94 else:
95 while True:
96 try:
97 self.status = os.waitpid(pid, 0)
98 except KeyboardInterrupt:
99 pass
100 except OSError, e:
101 if e.errno != errno.EINTR:
102 break
103
104 return self.status
105
106 return self._exec_engine(cmd, _exec, wait)
107
108
109
110 - def echo(self, msg):
111 """
112 Echo a message to terminal output
113 """
114
115 def _echo():
116 print(msg)
117
118 return self._exec_engine("echo", _echo)
119
120
121
123 """
124 Print prompt and wait for the key to be pressed
125 """
126
127 sys.stdout.write(bstring(msg))
128 sys.stdout.flush()
129
130 while True:
131 try:
132 m = os.read(sys.stdin.fileno(), 1024)
133 if key in m:
134 break
135 except OSError, e:
136 if e.errno != errno.EINTR:
137 break
138
139
140
142 """
143 Execute command engine
144 """
145
146 self.xyz.screen.clear()
147 stdout = sys.stdout
148 self.xyz.screen.stop()
149
150 _current_term = None
151
152
153 if self.xyz.term is not None:
154 _current_term = core.utils.term_settings()[-1]
155 core.utils.restore_term(self.xyz.term)
156
157
158
159 stdout.write("\x1b[H\x1b[2J")
160
161 stdout.write("%s%s\n" %
162 (bstring(
163 self.xyz.conf[u"plugins"][":sys:cmd"][u"prompt"]),
164 cmd))
165 stdout.flush()
166
167 def _sigwinch(_a, _b):
168 self.xyz.screen.resized = True
169
170 signal.signal(signal.SIGWINCH, _sigwinch)
171
172 status = cmdf()
173
174 if _current_term is not None:
175 core.utils.restore_term(_current_term)
176
177 if wait == True or (wait != False and self.conf["wait"]):
178 self._press_key(_(u"Press ENTER to continue..."), "\n")
179
180 self.xyz.screen.start()
181
182 return status
183