Chris@87
|
1 #!/usr/bin/env python
|
Chris@87
|
2 """
|
Chris@87
|
3 exec_command
|
Chris@87
|
4
|
Chris@87
|
5 Implements exec_command function that is (almost) equivalent to
|
Chris@87
|
6 commands.getstatusoutput function but on NT, DOS systems the
|
Chris@87
|
7 returned status is actually correct (though, the returned status
|
Chris@87
|
8 values may be different by a factor). In addition, exec_command
|
Chris@87
|
9 takes keyword arguments for (re-)defining environment variables.
|
Chris@87
|
10
|
Chris@87
|
11 Provides functions:
|
Chris@87
|
12 exec_command --- execute command in a specified directory and
|
Chris@87
|
13 in the modified environment.
|
Chris@87
|
14 find_executable --- locate a command using info from environment
|
Chris@87
|
15 variable PATH. Equivalent to posix `which`
|
Chris@87
|
16 command.
|
Chris@87
|
17
|
Chris@87
|
18 Author: Pearu Peterson <pearu@cens.ioc.ee>
|
Chris@87
|
19 Created: 11 January 2003
|
Chris@87
|
20
|
Chris@87
|
21 Requires: Python 2.x
|
Chris@87
|
22
|
Chris@87
|
23 Succesfully tested on:
|
Chris@87
|
24 os.name | sys.platform | comments
|
Chris@87
|
25 --------+--------------+----------
|
Chris@87
|
26 posix | linux2 | Debian (sid) Linux, Python 2.1.3+, 2.2.3+, 2.3.3
|
Chris@87
|
27 PyCrust 0.9.3, Idle 1.0.2
|
Chris@87
|
28 posix | linux2 | Red Hat 9 Linux, Python 2.1.3, 2.2.2, 2.3.2
|
Chris@87
|
29 posix | sunos5 | SunOS 5.9, Python 2.2, 2.3.2
|
Chris@87
|
30 posix | darwin | Darwin 7.2.0, Python 2.3
|
Chris@87
|
31 nt | win32 | Windows Me
|
Chris@87
|
32 Python 2.3(EE), Idle 1.0, PyCrust 0.7.2
|
Chris@87
|
33 Python 2.1.1 Idle 0.8
|
Chris@87
|
34 nt | win32 | Windows 98, Python 2.1.1. Idle 0.8
|
Chris@87
|
35 nt | win32 | Cygwin 98-4.10, Python 2.1.1(MSC) - echo tests
|
Chris@87
|
36 fail i.e. redefining environment variables may
|
Chris@87
|
37 not work. FIXED: don't use cygwin echo!
|
Chris@87
|
38 Comment: also `cmd /c echo` will not work
|
Chris@87
|
39 but redefining environment variables do work.
|
Chris@87
|
40 posix | cygwin | Cygwin 98-4.10, Python 2.3.3(cygming special)
|
Chris@87
|
41 nt | win32 | Windows XP, Python 2.3.3
|
Chris@87
|
42
|
Chris@87
|
43 Known bugs:
|
Chris@87
|
44 - Tests, that send messages to stderr, fail when executed from MSYS prompt
|
Chris@87
|
45 because the messages are lost at some point.
|
Chris@87
|
46 """
|
Chris@87
|
47 from __future__ import division, absolute_import, print_function
|
Chris@87
|
48
|
Chris@87
|
49 __all__ = ['exec_command', 'find_executable']
|
Chris@87
|
50
|
Chris@87
|
51 import os
|
Chris@87
|
52 import sys
|
Chris@87
|
53 import shlex
|
Chris@87
|
54
|
Chris@87
|
55 from numpy.distutils.misc_util import is_sequence, make_temp_file
|
Chris@87
|
56 from numpy.distutils import log
|
Chris@87
|
57 from numpy.distutils.compat import get_exception
|
Chris@87
|
58
|
Chris@87
|
59 from numpy.compat import open_latin1
|
Chris@87
|
60
|
Chris@87
|
61 def temp_file_name():
|
Chris@87
|
62 fo, name = make_temp_file()
|
Chris@87
|
63 fo.close()
|
Chris@87
|
64 return name
|
Chris@87
|
65
|
Chris@87
|
66 def get_pythonexe():
|
Chris@87
|
67 pythonexe = sys.executable
|
Chris@87
|
68 if os.name in ['nt', 'dos']:
|
Chris@87
|
69 fdir, fn = os.path.split(pythonexe)
|
Chris@87
|
70 fn = fn.upper().replace('PYTHONW', 'PYTHON')
|
Chris@87
|
71 pythonexe = os.path.join(fdir, fn)
|
Chris@87
|
72 assert os.path.isfile(pythonexe), '%r is not a file' % (pythonexe,)
|
Chris@87
|
73 return pythonexe
|
Chris@87
|
74
|
Chris@87
|
75 def splitcmdline(line):
|
Chris@87
|
76 import warnings
|
Chris@87
|
77 warnings.warn('splitcmdline is deprecated; use shlex.split',
|
Chris@87
|
78 DeprecationWarning)
|
Chris@87
|
79 return shlex.split(line)
|
Chris@87
|
80
|
Chris@87
|
81 def find_executable(exe, path=None, _cache={}):
|
Chris@87
|
82 """Return full path of a executable or None.
|
Chris@87
|
83
|
Chris@87
|
84 Symbolic links are not followed.
|
Chris@87
|
85 """
|
Chris@87
|
86 key = exe, path
|
Chris@87
|
87 try:
|
Chris@87
|
88 return _cache[key]
|
Chris@87
|
89 except KeyError:
|
Chris@87
|
90 pass
|
Chris@87
|
91 log.debug('find_executable(%r)' % exe)
|
Chris@87
|
92 orig_exe = exe
|
Chris@87
|
93
|
Chris@87
|
94 if path is None:
|
Chris@87
|
95 path = os.environ.get('PATH', os.defpath)
|
Chris@87
|
96 if os.name=='posix':
|
Chris@87
|
97 realpath = os.path.realpath
|
Chris@87
|
98 else:
|
Chris@87
|
99 realpath = lambda a:a
|
Chris@87
|
100
|
Chris@87
|
101 if exe.startswith('"'):
|
Chris@87
|
102 exe = exe[1:-1]
|
Chris@87
|
103
|
Chris@87
|
104 suffixes = ['']
|
Chris@87
|
105 if os.name in ['nt', 'dos', 'os2']:
|
Chris@87
|
106 fn, ext = os.path.splitext(exe)
|
Chris@87
|
107 extra_suffixes = ['.exe', '.com', '.bat']
|
Chris@87
|
108 if ext.lower() not in extra_suffixes:
|
Chris@87
|
109 suffixes = extra_suffixes
|
Chris@87
|
110
|
Chris@87
|
111 if os.path.isabs(exe):
|
Chris@87
|
112 paths = ['']
|
Chris@87
|
113 else:
|
Chris@87
|
114 paths = [ os.path.abspath(p) for p in path.split(os.pathsep) ]
|
Chris@87
|
115
|
Chris@87
|
116 for path in paths:
|
Chris@87
|
117 fn = os.path.join(path, exe)
|
Chris@87
|
118 for s in suffixes:
|
Chris@87
|
119 f_ext = fn+s
|
Chris@87
|
120 if not os.path.islink(f_ext):
|
Chris@87
|
121 f_ext = realpath(f_ext)
|
Chris@87
|
122 if os.path.isfile(f_ext) and os.access(f_ext, os.X_OK):
|
Chris@87
|
123 log.info('Found executable %s' % f_ext)
|
Chris@87
|
124 _cache[key] = f_ext
|
Chris@87
|
125 return f_ext
|
Chris@87
|
126
|
Chris@87
|
127 log.warn('Could not locate executable %s' % orig_exe)
|
Chris@87
|
128 return None
|
Chris@87
|
129
|
Chris@87
|
130 ############################################################
|
Chris@87
|
131
|
Chris@87
|
132 def _preserve_environment( names ):
|
Chris@87
|
133 log.debug('_preserve_environment(%r)' % (names))
|
Chris@87
|
134 env = {}
|
Chris@87
|
135 for name in names:
|
Chris@87
|
136 env[name] = os.environ.get(name)
|
Chris@87
|
137 return env
|
Chris@87
|
138
|
Chris@87
|
139 def _update_environment( **env ):
|
Chris@87
|
140 log.debug('_update_environment(...)')
|
Chris@87
|
141 for name, value in env.items():
|
Chris@87
|
142 os.environ[name] = value or ''
|
Chris@87
|
143
|
Chris@87
|
144 def _supports_fileno(stream):
|
Chris@87
|
145 """
|
Chris@87
|
146 Returns True if 'stream' supports the file descriptor and allows fileno().
|
Chris@87
|
147 """
|
Chris@87
|
148 if hasattr(stream, 'fileno'):
|
Chris@87
|
149 try:
|
Chris@87
|
150 r = stream.fileno()
|
Chris@87
|
151 return True
|
Chris@87
|
152 except IOError:
|
Chris@87
|
153 return False
|
Chris@87
|
154 else:
|
Chris@87
|
155 return False
|
Chris@87
|
156
|
Chris@87
|
157 def exec_command( command,
|
Chris@87
|
158 execute_in='', use_shell=None, use_tee = None,
|
Chris@87
|
159 _with_python = 1,
|
Chris@87
|
160 **env ):
|
Chris@87
|
161 """ Return (status,output) of executed command.
|
Chris@87
|
162
|
Chris@87
|
163 command is a concatenated string of executable and arguments.
|
Chris@87
|
164 The output contains both stdout and stderr messages.
|
Chris@87
|
165 The following special keyword arguments can be used:
|
Chris@87
|
166 use_shell - execute `sh -c command`
|
Chris@87
|
167 use_tee - pipe the output of command through tee
|
Chris@87
|
168 execute_in - before run command `cd execute_in` and after `cd -`.
|
Chris@87
|
169
|
Chris@87
|
170 On NT, DOS systems the returned status is correct for external commands.
|
Chris@87
|
171 Wild cards will not work for non-posix systems or when use_shell=0.
|
Chris@87
|
172 """
|
Chris@87
|
173 log.debug('exec_command(%r,%s)' % (command,\
|
Chris@87
|
174 ','.join(['%s=%r'%kv for kv in env.items()])))
|
Chris@87
|
175
|
Chris@87
|
176 if use_tee is None:
|
Chris@87
|
177 use_tee = os.name=='posix'
|
Chris@87
|
178 if use_shell is None:
|
Chris@87
|
179 use_shell = os.name=='posix'
|
Chris@87
|
180 execute_in = os.path.abspath(execute_in)
|
Chris@87
|
181 oldcwd = os.path.abspath(os.getcwd())
|
Chris@87
|
182
|
Chris@87
|
183 if __name__[-12:] == 'exec_command':
|
Chris@87
|
184 exec_dir = os.path.dirname(os.path.abspath(__file__))
|
Chris@87
|
185 elif os.path.isfile('exec_command.py'):
|
Chris@87
|
186 exec_dir = os.path.abspath('.')
|
Chris@87
|
187 else:
|
Chris@87
|
188 exec_dir = os.path.abspath(sys.argv[0])
|
Chris@87
|
189 if os.path.isfile(exec_dir):
|
Chris@87
|
190 exec_dir = os.path.dirname(exec_dir)
|
Chris@87
|
191
|
Chris@87
|
192 if oldcwd!=execute_in:
|
Chris@87
|
193 os.chdir(execute_in)
|
Chris@87
|
194 log.debug('New cwd: %s' % execute_in)
|
Chris@87
|
195 else:
|
Chris@87
|
196 log.debug('Retaining cwd: %s' % oldcwd)
|
Chris@87
|
197
|
Chris@87
|
198 oldenv = _preserve_environment( list(env.keys()) )
|
Chris@87
|
199 _update_environment( **env )
|
Chris@87
|
200
|
Chris@87
|
201 try:
|
Chris@87
|
202 # _exec_command is robust but slow, it relies on
|
Chris@87
|
203 # usable sys.std*.fileno() descriptors. If they
|
Chris@87
|
204 # are bad (like in win32 Idle, PyCrust environments)
|
Chris@87
|
205 # then _exec_command_python (even slower)
|
Chris@87
|
206 # will be used as a last resort.
|
Chris@87
|
207 #
|
Chris@87
|
208 # _exec_command_posix uses os.system and is faster
|
Chris@87
|
209 # but not on all platforms os.system will return
|
Chris@87
|
210 # a correct status.
|
Chris@87
|
211 if (_with_python and _supports_fileno(sys.stdout) and
|
Chris@87
|
212 sys.stdout.fileno() == -1):
|
Chris@87
|
213 st = _exec_command_python(command,
|
Chris@87
|
214 exec_command_dir = exec_dir,
|
Chris@87
|
215 **env)
|
Chris@87
|
216 elif os.name=='posix':
|
Chris@87
|
217 st = _exec_command_posix(command,
|
Chris@87
|
218 use_shell=use_shell,
|
Chris@87
|
219 use_tee=use_tee,
|
Chris@87
|
220 **env)
|
Chris@87
|
221 else:
|
Chris@87
|
222 st = _exec_command(command, use_shell=use_shell,
|
Chris@87
|
223 use_tee=use_tee,**env)
|
Chris@87
|
224 finally:
|
Chris@87
|
225 if oldcwd!=execute_in:
|
Chris@87
|
226 os.chdir(oldcwd)
|
Chris@87
|
227 log.debug('Restored cwd to %s' % oldcwd)
|
Chris@87
|
228 _update_environment(**oldenv)
|
Chris@87
|
229
|
Chris@87
|
230 return st
|
Chris@87
|
231
|
Chris@87
|
232 def _exec_command_posix( command,
|
Chris@87
|
233 use_shell = None,
|
Chris@87
|
234 use_tee = None,
|
Chris@87
|
235 **env ):
|
Chris@87
|
236 log.debug('_exec_command_posix(...)')
|
Chris@87
|
237
|
Chris@87
|
238 if is_sequence(command):
|
Chris@87
|
239 command_str = ' '.join(list(command))
|
Chris@87
|
240 else:
|
Chris@87
|
241 command_str = command
|
Chris@87
|
242
|
Chris@87
|
243 tmpfile = temp_file_name()
|
Chris@87
|
244 stsfile = None
|
Chris@87
|
245 if use_tee:
|
Chris@87
|
246 stsfile = temp_file_name()
|
Chris@87
|
247 filter = ''
|
Chris@87
|
248 if use_tee == 2:
|
Chris@87
|
249 filter = r'| tr -cd "\n" | tr "\n" "."; echo'
|
Chris@87
|
250 command_posix = '( %s ; echo $? > %s ) 2>&1 | tee %s %s'\
|
Chris@87
|
251 % (command_str, stsfile, tmpfile, filter)
|
Chris@87
|
252 else:
|
Chris@87
|
253 stsfile = temp_file_name()
|
Chris@87
|
254 command_posix = '( %s ; echo $? > %s ) > %s 2>&1'\
|
Chris@87
|
255 % (command_str, stsfile, tmpfile)
|
Chris@87
|
256 #command_posix = '( %s ) > %s 2>&1' % (command_str,tmpfile)
|
Chris@87
|
257
|
Chris@87
|
258 log.debug('Running os.system(%r)' % (command_posix))
|
Chris@87
|
259 status = os.system(command_posix)
|
Chris@87
|
260
|
Chris@87
|
261 if use_tee:
|
Chris@87
|
262 if status:
|
Chris@87
|
263 # if command_tee fails then fall back to robust exec_command
|
Chris@87
|
264 log.warn('_exec_command_posix failed (status=%s)' % status)
|
Chris@87
|
265 return _exec_command(command, use_shell=use_shell, **env)
|
Chris@87
|
266
|
Chris@87
|
267 if stsfile is not None:
|
Chris@87
|
268 f = open_latin1(stsfile, 'r')
|
Chris@87
|
269 status_text = f.read()
|
Chris@87
|
270 status = int(status_text)
|
Chris@87
|
271 f.close()
|
Chris@87
|
272 os.remove(stsfile)
|
Chris@87
|
273
|
Chris@87
|
274 f = open_latin1(tmpfile, 'r')
|
Chris@87
|
275 text = f.read()
|
Chris@87
|
276 f.close()
|
Chris@87
|
277 os.remove(tmpfile)
|
Chris@87
|
278
|
Chris@87
|
279 if text[-1:]=='\n':
|
Chris@87
|
280 text = text[:-1]
|
Chris@87
|
281
|
Chris@87
|
282 return status, text
|
Chris@87
|
283
|
Chris@87
|
284
|
Chris@87
|
285 def _exec_command_python(command,
|
Chris@87
|
286 exec_command_dir='', **env):
|
Chris@87
|
287 log.debug('_exec_command_python(...)')
|
Chris@87
|
288
|
Chris@87
|
289 python_exe = get_pythonexe()
|
Chris@87
|
290 cmdfile = temp_file_name()
|
Chris@87
|
291 stsfile = temp_file_name()
|
Chris@87
|
292 outfile = temp_file_name()
|
Chris@87
|
293
|
Chris@87
|
294 f = open(cmdfile, 'w')
|
Chris@87
|
295 f.write('import os\n')
|
Chris@87
|
296 f.write('import sys\n')
|
Chris@87
|
297 f.write('sys.path.insert(0,%r)\n' % (exec_command_dir))
|
Chris@87
|
298 f.write('from exec_command import exec_command\n')
|
Chris@87
|
299 f.write('del sys.path[0]\n')
|
Chris@87
|
300 f.write('cmd = %r\n' % command)
|
Chris@87
|
301 f.write('os.environ = %r\n' % (os.environ))
|
Chris@87
|
302 f.write('s,o = exec_command(cmd, _with_python=0, **%r)\n' % (env))
|
Chris@87
|
303 f.write('f=open(%r,"w")\nf.write(str(s))\nf.close()\n' % (stsfile))
|
Chris@87
|
304 f.write('f=open(%r,"w")\nf.write(o)\nf.close()\n' % (outfile))
|
Chris@87
|
305 f.close()
|
Chris@87
|
306
|
Chris@87
|
307 cmd = '%s %s' % (python_exe, cmdfile)
|
Chris@87
|
308 status = os.system(cmd)
|
Chris@87
|
309 if status:
|
Chris@87
|
310 raise RuntimeError("%r failed" % (cmd,))
|
Chris@87
|
311 os.remove(cmdfile)
|
Chris@87
|
312
|
Chris@87
|
313 f = open_latin1(stsfile, 'r')
|
Chris@87
|
314 status = int(f.read())
|
Chris@87
|
315 f.close()
|
Chris@87
|
316 os.remove(stsfile)
|
Chris@87
|
317
|
Chris@87
|
318 f = open_latin1(outfile, 'r')
|
Chris@87
|
319 text = f.read()
|
Chris@87
|
320 f.close()
|
Chris@87
|
321 os.remove(outfile)
|
Chris@87
|
322
|
Chris@87
|
323 return status, text
|
Chris@87
|
324
|
Chris@87
|
325 def quote_arg(arg):
|
Chris@87
|
326 if arg[0]!='"' and ' ' in arg:
|
Chris@87
|
327 return '"%s"' % arg
|
Chris@87
|
328 return arg
|
Chris@87
|
329
|
Chris@87
|
330 def _exec_command( command, use_shell=None, use_tee = None, **env ):
|
Chris@87
|
331 log.debug('_exec_command(...)')
|
Chris@87
|
332
|
Chris@87
|
333 if use_shell is None:
|
Chris@87
|
334 use_shell = os.name=='posix'
|
Chris@87
|
335 if use_tee is None:
|
Chris@87
|
336 use_tee = os.name=='posix'
|
Chris@87
|
337 using_command = 0
|
Chris@87
|
338 if use_shell:
|
Chris@87
|
339 # We use shell (unless use_shell==0) so that wildcards can be
|
Chris@87
|
340 # used.
|
Chris@87
|
341 sh = os.environ.get('SHELL', '/bin/sh')
|
Chris@87
|
342 if is_sequence(command):
|
Chris@87
|
343 argv = [sh, '-c', ' '.join(list(command))]
|
Chris@87
|
344 else:
|
Chris@87
|
345 argv = [sh, '-c', command]
|
Chris@87
|
346 else:
|
Chris@87
|
347 # On NT, DOS we avoid using command.com as it's exit status is
|
Chris@87
|
348 # not related to the exit status of a command.
|
Chris@87
|
349 if is_sequence(command):
|
Chris@87
|
350 argv = command[:]
|
Chris@87
|
351 else:
|
Chris@87
|
352 argv = shlex.split(command)
|
Chris@87
|
353
|
Chris@87
|
354 if hasattr(os, 'spawnvpe'):
|
Chris@87
|
355 spawn_command = os.spawnvpe
|
Chris@87
|
356 else:
|
Chris@87
|
357 spawn_command = os.spawnve
|
Chris@87
|
358 argv[0] = find_executable(argv[0]) or argv[0]
|
Chris@87
|
359 if not os.path.isfile(argv[0]):
|
Chris@87
|
360 log.warn('Executable %s does not exist' % (argv[0]))
|
Chris@87
|
361 if os.name in ['nt', 'dos']:
|
Chris@87
|
362 # argv[0] might be internal command
|
Chris@87
|
363 argv = [os.environ['COMSPEC'], '/C'] + argv
|
Chris@87
|
364 using_command = 1
|
Chris@87
|
365
|
Chris@87
|
366 _so_has_fileno = _supports_fileno(sys.stdout)
|
Chris@87
|
367 _se_has_fileno = _supports_fileno(sys.stderr)
|
Chris@87
|
368 so_flush = sys.stdout.flush
|
Chris@87
|
369 se_flush = sys.stderr.flush
|
Chris@87
|
370 if _so_has_fileno:
|
Chris@87
|
371 so_fileno = sys.stdout.fileno()
|
Chris@87
|
372 so_dup = os.dup(so_fileno)
|
Chris@87
|
373 if _se_has_fileno:
|
Chris@87
|
374 se_fileno = sys.stderr.fileno()
|
Chris@87
|
375 se_dup = os.dup(se_fileno)
|
Chris@87
|
376
|
Chris@87
|
377 outfile = temp_file_name()
|
Chris@87
|
378 fout = open(outfile, 'w')
|
Chris@87
|
379 if using_command:
|
Chris@87
|
380 errfile = temp_file_name()
|
Chris@87
|
381 ferr = open(errfile, 'w')
|
Chris@87
|
382
|
Chris@87
|
383 log.debug('Running %s(%s,%r,%r,os.environ)' \
|
Chris@87
|
384 % (spawn_command.__name__, os.P_WAIT, argv[0], argv))
|
Chris@87
|
385
|
Chris@87
|
386 argv0 = argv[0]
|
Chris@87
|
387 if not using_command:
|
Chris@87
|
388 argv[0] = quote_arg(argv0)
|
Chris@87
|
389
|
Chris@87
|
390 so_flush()
|
Chris@87
|
391 se_flush()
|
Chris@87
|
392 if _so_has_fileno:
|
Chris@87
|
393 os.dup2(fout.fileno(), so_fileno)
|
Chris@87
|
394
|
Chris@87
|
395 if _se_has_fileno:
|
Chris@87
|
396 if using_command:
|
Chris@87
|
397 #XXX: disabled for now as it does not work from cmd under win32.
|
Chris@87
|
398 # Tests fail on msys
|
Chris@87
|
399 os.dup2(ferr.fileno(), se_fileno)
|
Chris@87
|
400 else:
|
Chris@87
|
401 os.dup2(fout.fileno(), se_fileno)
|
Chris@87
|
402 try:
|
Chris@87
|
403 status = spawn_command(os.P_WAIT, argv0, argv, os.environ)
|
Chris@87
|
404 except OSError:
|
Chris@87
|
405 errmess = str(get_exception())
|
Chris@87
|
406 status = 999
|
Chris@87
|
407 sys.stderr.write('%s: %s'%(errmess, argv[0]))
|
Chris@87
|
408
|
Chris@87
|
409 so_flush()
|
Chris@87
|
410 se_flush()
|
Chris@87
|
411 if _so_has_fileno:
|
Chris@87
|
412 os.dup2(so_dup, so_fileno)
|
Chris@87
|
413 if _se_has_fileno:
|
Chris@87
|
414 os.dup2(se_dup, se_fileno)
|
Chris@87
|
415
|
Chris@87
|
416 fout.close()
|
Chris@87
|
417 fout = open_latin1(outfile, 'r')
|
Chris@87
|
418 text = fout.read()
|
Chris@87
|
419 fout.close()
|
Chris@87
|
420 os.remove(outfile)
|
Chris@87
|
421
|
Chris@87
|
422 if using_command:
|
Chris@87
|
423 ferr.close()
|
Chris@87
|
424 ferr = open_latin1(errfile, 'r')
|
Chris@87
|
425 errmess = ferr.read()
|
Chris@87
|
426 ferr.close()
|
Chris@87
|
427 os.remove(errfile)
|
Chris@87
|
428 if errmess and not status:
|
Chris@87
|
429 # Not sure how to handle the case where errmess
|
Chris@87
|
430 # contains only warning messages and that should
|
Chris@87
|
431 # not be treated as errors.
|
Chris@87
|
432 #status = 998
|
Chris@87
|
433 if text:
|
Chris@87
|
434 text = text + '\n'
|
Chris@87
|
435 #text = '%sCOMMAND %r FAILED: %s' %(text,command,errmess)
|
Chris@87
|
436 text = text + errmess
|
Chris@87
|
437 print (errmess)
|
Chris@87
|
438 if text[-1:]=='\n':
|
Chris@87
|
439 text = text[:-1]
|
Chris@87
|
440 if status is None:
|
Chris@87
|
441 status = 0
|
Chris@87
|
442
|
Chris@87
|
443 if use_tee:
|
Chris@87
|
444 print (text)
|
Chris@87
|
445
|
Chris@87
|
446 return status, text
|
Chris@87
|
447
|
Chris@87
|
448
|
Chris@87
|
449 def test_nt(**kws):
|
Chris@87
|
450 pythonexe = get_pythonexe()
|
Chris@87
|
451 echo = find_executable('echo')
|
Chris@87
|
452 using_cygwin_echo = echo != 'echo'
|
Chris@87
|
453 if using_cygwin_echo:
|
Chris@87
|
454 log.warn('Using cygwin echo in win32 environment is not supported')
|
Chris@87
|
455
|
Chris@87
|
456 s, o=exec_command(pythonexe\
|
Chris@87
|
457 +' -c "import os;print os.environ.get(\'AAA\',\'\')"')
|
Chris@87
|
458 assert s==0 and o=='', (s, o)
|
Chris@87
|
459
|
Chris@87
|
460 s, o=exec_command(pythonexe\
|
Chris@87
|
461 +' -c "import os;print os.environ.get(\'AAA\')"',
|
Chris@87
|
462 AAA='Tere')
|
Chris@87
|
463 assert s==0 and o=='Tere', (s, o)
|
Chris@87
|
464
|
Chris@87
|
465 os.environ['BBB'] = 'Hi'
|
Chris@87
|
466 s, o=exec_command(pythonexe\
|
Chris@87
|
467 +' -c "import os;print os.environ.get(\'BBB\',\'\')"')
|
Chris@87
|
468 assert s==0 and o=='Hi', (s, o)
|
Chris@87
|
469
|
Chris@87
|
470 s, o=exec_command(pythonexe\
|
Chris@87
|
471 +' -c "import os;print os.environ.get(\'BBB\',\'\')"',
|
Chris@87
|
472 BBB='Hey')
|
Chris@87
|
473 assert s==0 and o=='Hey', (s, o)
|
Chris@87
|
474
|
Chris@87
|
475 s, o=exec_command(pythonexe\
|
Chris@87
|
476 +' -c "import os;print os.environ.get(\'BBB\',\'\')"')
|
Chris@87
|
477 assert s==0 and o=='Hi', (s, o)
|
Chris@87
|
478 elif 0:
|
Chris@87
|
479 s, o=exec_command('echo Hello')
|
Chris@87
|
480 assert s==0 and o=='Hello', (s, o)
|
Chris@87
|
481
|
Chris@87
|
482 s, o=exec_command('echo a%AAA%')
|
Chris@87
|
483 assert s==0 and o=='a', (s, o)
|
Chris@87
|
484
|
Chris@87
|
485 s, o=exec_command('echo a%AAA%', AAA='Tere')
|
Chris@87
|
486 assert s==0 and o=='aTere', (s, o)
|
Chris@87
|
487
|
Chris@87
|
488 os.environ['BBB'] = 'Hi'
|
Chris@87
|
489 s, o=exec_command('echo a%BBB%')
|
Chris@87
|
490 assert s==0 and o=='aHi', (s, o)
|
Chris@87
|
491
|
Chris@87
|
492 s, o=exec_command('echo a%BBB%', BBB='Hey')
|
Chris@87
|
493 assert s==0 and o=='aHey', (s, o)
|
Chris@87
|
494 s, o=exec_command('echo a%BBB%')
|
Chris@87
|
495 assert s==0 and o=='aHi', (s, o)
|
Chris@87
|
496
|
Chris@87
|
497 s, o=exec_command('this_is_not_a_command')
|
Chris@87
|
498 assert s and o!='', (s, o)
|
Chris@87
|
499
|
Chris@87
|
500 s, o=exec_command('type not_existing_file')
|
Chris@87
|
501 assert s and o!='', (s, o)
|
Chris@87
|
502
|
Chris@87
|
503 s, o=exec_command('echo path=%path%')
|
Chris@87
|
504 assert s==0 and o!='', (s, o)
|
Chris@87
|
505
|
Chris@87
|
506 s, o=exec_command('%s -c "import sys;sys.stderr.write(sys.platform)"' \
|
Chris@87
|
507 % pythonexe)
|
Chris@87
|
508 assert s==0 and o=='win32', (s, o)
|
Chris@87
|
509
|
Chris@87
|
510 s, o=exec_command('%s -c "raise \'Ignore me.\'"' % pythonexe)
|
Chris@87
|
511 assert s==1 and o, (s, o)
|
Chris@87
|
512
|
Chris@87
|
513 s, o=exec_command('%s -c "import sys;sys.stderr.write(\'0\');sys.stderr.write(\'1\');sys.stderr.write(\'2\')"'\
|
Chris@87
|
514 % pythonexe)
|
Chris@87
|
515 assert s==0 and o=='012', (s, o)
|
Chris@87
|
516
|
Chris@87
|
517 s, o=exec_command('%s -c "import sys;sys.exit(15)"' % pythonexe)
|
Chris@87
|
518 assert s==15 and o=='', (s, o)
|
Chris@87
|
519
|
Chris@87
|
520 s, o=exec_command('%s -c "print \'Heipa\'"' % pythonexe)
|
Chris@87
|
521 assert s==0 and o=='Heipa', (s, o)
|
Chris@87
|
522
|
Chris@87
|
523 print ('ok')
|
Chris@87
|
524
|
Chris@87
|
525 def test_posix(**kws):
|
Chris@87
|
526 s, o=exec_command("echo Hello",**kws)
|
Chris@87
|
527 assert s==0 and o=='Hello', (s, o)
|
Chris@87
|
528
|
Chris@87
|
529 s, o=exec_command('echo $AAA',**kws)
|
Chris@87
|
530 assert s==0 and o=='', (s, o)
|
Chris@87
|
531
|
Chris@87
|
532 s, o=exec_command('echo "$AAA"',AAA='Tere',**kws)
|
Chris@87
|
533 assert s==0 and o=='Tere', (s, o)
|
Chris@87
|
534
|
Chris@87
|
535
|
Chris@87
|
536 s, o=exec_command('echo "$AAA"',**kws)
|
Chris@87
|
537 assert s==0 and o=='', (s, o)
|
Chris@87
|
538
|
Chris@87
|
539 os.environ['BBB'] = 'Hi'
|
Chris@87
|
540 s, o=exec_command('echo "$BBB"',**kws)
|
Chris@87
|
541 assert s==0 and o=='Hi', (s, o)
|
Chris@87
|
542
|
Chris@87
|
543 s, o=exec_command('echo "$BBB"',BBB='Hey',**kws)
|
Chris@87
|
544 assert s==0 and o=='Hey', (s, o)
|
Chris@87
|
545
|
Chris@87
|
546 s, o=exec_command('echo "$BBB"',**kws)
|
Chris@87
|
547 assert s==0 and o=='Hi', (s, o)
|
Chris@87
|
548
|
Chris@87
|
549
|
Chris@87
|
550 s, o=exec_command('this_is_not_a_command',**kws)
|
Chris@87
|
551 assert s!=0 and o!='', (s, o)
|
Chris@87
|
552
|
Chris@87
|
553 s, o=exec_command('echo path=$PATH',**kws)
|
Chris@87
|
554 assert s==0 and o!='', (s, o)
|
Chris@87
|
555
|
Chris@87
|
556 s, o=exec_command('python -c "import sys,os;sys.stderr.write(os.name)"',**kws)
|
Chris@87
|
557 assert s==0 and o=='posix', (s, o)
|
Chris@87
|
558
|
Chris@87
|
559 s, o=exec_command('python -c "raise \'Ignore me.\'"',**kws)
|
Chris@87
|
560 assert s==1 and o, (s, o)
|
Chris@87
|
561
|
Chris@87
|
562 s, o=exec_command('python -c "import sys;sys.stderr.write(\'0\');sys.stderr.write(\'1\');sys.stderr.write(\'2\')"',**kws)
|
Chris@87
|
563 assert s==0 and o=='012', (s, o)
|
Chris@87
|
564
|
Chris@87
|
565 s, o=exec_command('python -c "import sys;sys.exit(15)"',**kws)
|
Chris@87
|
566 assert s==15 and o=='', (s, o)
|
Chris@87
|
567
|
Chris@87
|
568 s, o=exec_command('python -c "print \'Heipa\'"',**kws)
|
Chris@87
|
569 assert s==0 and o=='Heipa', (s, o)
|
Chris@87
|
570
|
Chris@87
|
571 print ('ok')
|
Chris@87
|
572
|
Chris@87
|
573 def test_execute_in(**kws):
|
Chris@87
|
574 pythonexe = get_pythonexe()
|
Chris@87
|
575 tmpfile = temp_file_name()
|
Chris@87
|
576 fn = os.path.basename(tmpfile)
|
Chris@87
|
577 tmpdir = os.path.dirname(tmpfile)
|
Chris@87
|
578 f = open(tmpfile, 'w')
|
Chris@87
|
579 f.write('Hello')
|
Chris@87
|
580 f.close()
|
Chris@87
|
581
|
Chris@87
|
582 s, o = exec_command('%s -c "print \'Ignore the following IOError:\','\
|
Chris@87
|
583 'open(%r,\'r\')"' % (pythonexe, fn),**kws)
|
Chris@87
|
584 assert s and o!='', (s, o)
|
Chris@87
|
585 s, o = exec_command('%s -c "print open(%r,\'r\').read()"' % (pythonexe, fn),
|
Chris@87
|
586 execute_in = tmpdir,**kws)
|
Chris@87
|
587 assert s==0 and o=='Hello', (s, o)
|
Chris@87
|
588 os.remove(tmpfile)
|
Chris@87
|
589 print ('ok')
|
Chris@87
|
590
|
Chris@87
|
591 def test_svn(**kws):
|
Chris@87
|
592 s, o = exec_command(['svn', 'status'],**kws)
|
Chris@87
|
593 assert s, (s, o)
|
Chris@87
|
594 print ('svn ok')
|
Chris@87
|
595
|
Chris@87
|
596 def test_cl(**kws):
|
Chris@87
|
597 if os.name=='nt':
|
Chris@87
|
598 s, o = exec_command(['cl', '/V'],**kws)
|
Chris@87
|
599 assert s, (s, o)
|
Chris@87
|
600 print ('cl ok')
|
Chris@87
|
601
|
Chris@87
|
602 if os.name=='posix':
|
Chris@87
|
603 test = test_posix
|
Chris@87
|
604 elif os.name in ['nt', 'dos']:
|
Chris@87
|
605 test = test_nt
|
Chris@87
|
606 else:
|
Chris@87
|
607 raise NotImplementedError('exec_command tests for ', os.name)
|
Chris@87
|
608
|
Chris@87
|
609 ############################################################
|
Chris@87
|
610
|
Chris@87
|
611 if __name__ == "__main__":
|
Chris@87
|
612
|
Chris@87
|
613 test(use_tee=0)
|
Chris@87
|
614 test(use_tee=1)
|
Chris@87
|
615 test_execute_in(use_tee=0)
|
Chris@87
|
616 test_execute_in(use_tee=1)
|
Chris@87
|
617 test_svn(use_tee=1)
|
Chris@87
|
618 test_cl(use_tee=1)
|