1 __doc__ = """GNUmed general tools."""
2
3
4 __version__ = "$Revision: 1.13 $"
5 __author__ = "K. Hilbert <Karsten.Hilbert@gmx.net>"
6 __license__ = "GPL (details at http://www.gnu.org)"
7
8
9
10 import os, sys, logging
11
12
13 _log = logging.getLogger('gm.shell')
14 _log.info(__version__)
15
16
18 _log.debug('detecting [%s]', binary)
19
20
21 if os.access(binary, os.X_OK):
22 return (True, binary)
23
24
25 cmd = 'which %s' % binary
26 pipe = os.popen(cmd.encode(sys.getfilesystemencoding()), "r")
27 result = pipe.readline()
28 ret_code = pipe.close()
29 if ret_code is not None:
30 _log.debug('[%s] failed, exit code: %s', cmd, ret_code)
31 else:
32 result = result.strip('\r\n')
33 _log.debug('[%s] returned: %s', cmd, result)
34
35 if os.access(result, os.X_OK):
36 return (True, result)
37 else:
38 _log.debug('[%s] not detected with "which"', binary)
39
40
41
42 tmp = binary.lstrip()
43
44 if tmp.startswith('wine'):
45
46 tmp = tmp[4:].strip().strip('"')
47
48
49 if os.access(tmp, os.R_OK):
50 _log.debug('wine call with UNIX path')
51 return (True, binary)
52
53
54 cmd = 'winepath -u "%s"' % tmp
55 pipe = os.popen(cmd.encode(sys.getfilesystemencoding()), "r")
56 result = pipe.readline()
57 ret_code = pipe.close()
58 if ret_code is not None:
59 _log.debug('winepath failed')
60 else:
61 result = result.strip('\r\n')
62 if os.access(result, os.R_OK):
63 _log.debug('wine call with Windows path')
64 return (True, binary)
65 else:
66 _log.warning('"winepath -u %s" returned [%s] but the UNIX path is not verifiable', tmp, result)
67
68 return (False, None)
69
71
72 found = False
73 binary = None
74
75 for cmd in binaries:
76 _log.debug('looking for [%s]', cmd)
77
78 if cmd is None:
79 continue
80
81 found, binary = detect_external_binary(binary = cmd)
82 if found:
83 break
84
85 return (found, binary)
86
88 """Runs a command in a subshell via standard-C system().
89
90 <command>
91 The shell command to run including command line options.
92 <blocking>
93 This will make the code *block* until the shell command exits.
94 It will likely only work on UNIX shells where "cmd &" makes sense.
95 """
96 if acceptable_return_codes is None:
97 acceptable_return_codes = [0]
98
99 _log.debug('shell command >>>%s<<<', command)
100 _log.debug('blocking: %s', blocking)
101 _log.debug('acceptable return codes: %s', str(acceptable_return_codes))
102
103
104 command = command.strip()
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124 if blocking is True:
125 if command[-2:] == ' &':
126 command = command[:-2]
127 elif blocking is False:
128 if command[-2:] != ' &':
129 command += ' &'
130
131 _log.info('running shell command >>>%s<<<', command)
132
133 ret_val = os.system(command.encode(sys.getfilesystemencoding()))
134 _log.debug('os.system() returned: [%s]', ret_val)
135
136 exited_normally = False
137
138 if not hasattr(os, 'WIFEXITED'):
139 _log.debug('platform does not support exit status differentiation')
140 return exited_normally
141
142 _log.debug('exited via exit(): %s', os.WIFEXITED(ret_val))
143 if os.WIFEXITED(ret_val):
144 _log.debug('exit code: [%s]', os.WEXITSTATUS(ret_val))
145 exited_normally = (os.WEXITSTATUS(ret_val) in acceptable_return_codes)
146 _log.debug('normal exit: %s', exited_normally)
147 _log.debug('dumped core: %s', os.WCOREDUMP(ret_val))
148 _log.debug('stopped by signal: %s', os.WIFSIGNALED(ret_val))
149 if os.WIFSIGNALED(ret_val):
150 _log.debug('STOP signal was: [%s]', os.STOPSIG(ret_val))
151 _log.debug('TERM signal was: [%s]', os.TERMSIG(ret_val))
152
153 return exited_normally
154
156
157 found, binary = find_first_binary(binaries = binaries)
158
159 if not found:
160 if run_last_one_anyway:
161 binary = binaries[-1]
162 else:
163 _log.warning('cannot find any of: %s', binaries)
164 return False
165
166 return run_command_in_shell(command = '%s %s' % (binary, args), blocking = blocking)
167
168
169
170 if __name__ == '__main__':
171
172 if len(sys.argv) < 2:
173 sys.exit()
174
175 if sys.argv[1] != u'test':
176 sys.exit()
177
178 logging.basicConfig(level = logging.DEBUG)
179
181 found, path = detect_external_binary(binary = sys.argv[2])
182 if found:
183 print "found as:", path
184 else:
185 print sys.argv[2], "not found"
186
188 print "-------------------------------------"
189 print "running:", sys.argv[2]
190 if run_command_in_shell(command=sys.argv[2], blocking=True):
191 print "-------------------------------------"
192 print "success"
193 else:
194 print "-------------------------------------"
195 print "failure, consult log"
196
197 test_run_command_in_shell()
198
199
200
201