Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: build/android/pylib/cmd_helper.py

Issue 670463002: Revert of New run shell implementation for DeviceUtils (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | build/android/pylib/cmd_helper_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """A wrapper for subprocess to make calling shell commands easier.""" 5 """A wrapper for subprocess to make calling shell commands easier."""
6 6
7 import logging 7 import logging
8 import os 8 import os
9 import pipes 9 import pipes
10 import select 10 import select
11 import signal 11 import signal
12 import string
13 import StringIO 12 import StringIO
14 import subprocess 13 import subprocess
15 import time 14 import time
16 15
17 # fcntl is not available on Windows. 16 # fcntl is not available on Windows.
18 try: 17 try:
19 import fcntl 18 import fcntl
20 except ImportError: 19 except ImportError:
21 fcntl = None 20 fcntl = None
22 21
23 _SafeShellChars = frozenset(string.ascii_letters + string.digits + '@%_-+=:,./')
24
25 def SingleQuote(s):
26 """Return an shell-escaped version of the string using single quotes.
27
28 Reliably quote a string which may contain unsafe characters (e.g. space,
29 quote, or other special characters such as '$').
30
31 The returned value can be used in a shell command line as one token that gets
32 to be interpreted literally.
33
34 Args:
35 s: The string to quote.
36
37 Return:
38 The string quoted using single quotes.
39 """
40 return pipes.quote(s)
41
42 def DoubleQuote(s):
43 """Return an shell-escaped version of the string using double quotes.
44
45 Reliably quote a string which may contain unsafe characters (e.g. space
46 or quote characters), while retaining some shell features such as variable
47 interpolation.
48
49 The returned value can be used in a shell command line as one token that gets
50 to be further interpreted by the shell.
51
52 The set of characters that retain their special meaning may depend on the
53 shell implementation. This set usually includes: '$', '`', '\', '!', '*',
54 and '@'.
55
56 Args:
57 s: The string to quote.
58
59 Return:
60 The string quoted using double quotes.
61 """
62 if not s:
63 return '""'
64 elif all(c in _SafeShellChars for c in s):
65 return s
66 else:
67 return '"' + s.replace('"', '\\"') + '"'
68
69 22
70 def Popen(args, stdout=None, stderr=None, shell=None, cwd=None, env=None): 23 def Popen(args, stdout=None, stderr=None, shell=None, cwd=None, env=None):
71 return subprocess.Popen( 24 return subprocess.Popen(
72 args=args, cwd=cwd, stdout=stdout, stderr=stderr, 25 args=args, cwd=cwd, stdout=stdout, stderr=stderr,
73 shell=shell, close_fds=True, env=env, 26 shell=shell, close_fds=True, env=env,
74 preexec_fn=lambda: signal.signal(signal.SIGPIPE, signal.SIG_DFL)) 27 preexec_fn=lambda: signal.signal(signal.SIGPIPE, signal.SIG_DFL))
75 28
76 29
77 def Call(args, stdout=None, stderr=None, shell=None, cwd=None, env=None): 30 def Call(args, stdout=None, stderr=None, shell=None, cwd=None, env=None):
78 pipe = Popen(args, stdout=stdout, stderr=stderr, shell=shell, cwd=cwd, 31 pipe = Popen(args, stdout=stdout, stderr=stderr, shell=shell, cwd=cwd,
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 Returns: 81 Returns:
129 The 2-tuple (exit code, output). 82 The 2-tuple (exit code, output).
130 """ 83 """
131 if isinstance(args, basestring): 84 if isinstance(args, basestring):
132 args_repr = args 85 args_repr = args
133 if not shell: 86 if not shell:
134 raise Exception('string args must be run with shell=True') 87 raise Exception('string args must be run with shell=True')
135 elif shell: 88 elif shell:
136 raise Exception('array args must be run with shell=False') 89 raise Exception('array args must be run with shell=False')
137 else: 90 else:
138 args_repr = ' '.join(map(SingleQuote, args)) 91 args_repr = ' '.join(map(pipes.quote, args))
139 92
140 s = '[host]' 93 s = '[host]'
141 if cwd: 94 if cwd:
142 s += ':' + cwd 95 s += ':' + cwd
143 s += '> ' + args_repr 96 s += '> ' + args_repr
144 logging.info(s) 97 logging.info(s)
145 pipe = Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, 98 pipe = Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
146 shell=shell, cwd=cwd) 99 shell=shell, cwd=cwd)
147 stdout, stderr = pipe.communicate() 100 stdout, stderr = pipe.communicate()
148 101
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
205 break 158 break
206 finally: 159 finally:
207 try: 160 try:
208 # Make sure the process doesn't stick around if we fail with an 161 # Make sure the process doesn't stick around if we fail with an
209 # exception. 162 # exception.
210 process.kill() 163 process.kill()
211 except OSError: 164 except OSError:
212 pass 165 pass
213 process.wait() 166 process.wait()
214 return process.returncode, output.getvalue() 167 return process.returncode, output.getvalue()
OLDNEW
« no previous file with comments | « no previous file | build/android/pylib/cmd_helper_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698