Merge lp:~cjwatson/launchpad/shhh-no-shell into lp:launchpad

Proposed by Colin Watson
Status: Merged
Merged at revision: 18464
Proposed branch: lp:~cjwatson/launchpad/shhh-no-shell
Merge into: lp:launchpad
Diff against target: 106 lines (+31/-19)
1 file modified
utilities/shhh.py (+31/-19)
To merge this branch: bzr merge lp:~cjwatson/launchpad/shhh-no-shell
Reviewer Review Type Date Requested Status
William Grant code Approve
Review via email: mp+330155@code.launchpad.net

Commit message

Rework utilities/shhh.py to invoke the subsidiary command directly rather than via a shell.

Description of the change

shell=True delenda est.

To post a comment you must log in.
Revision history for this message
William Grant (wgrant) :
review: Approve (code)
Revision history for this message
Colin Watson (cjwatson) :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'utilities/shhh.py'
--- utilities/shhh.py 2012-01-01 03:10:25 +0000
+++ utilities/shhh.py 2017-09-04 11:58:53 +0000
@@ -1,14 +1,15 @@
1#! /usr/bin/python -S1#! /usr/bin/python -S
2#2#
3# Copyright 2009 Canonical Ltd. This software is licensed under the3# Copyright 2009-2017 Canonical Ltd. This software is licensed under the
4# GNU Affero General Public License version 3 (see the file LICENSE).4# GNU Affero General Public License version 3 (see the file LICENSE).
55
6"""6"""
7Run a command and suppress output unless it returns a non-zero exit status7Run a command and suppress output unless it returns a non-zero exit status.
8"""8"""
99
10__metaclass__ = type10__metaclass__ = type
1111
12import os
12from subprocess import (13from subprocess import (
13 PIPE,14 PIPE,
14 Popen,15 Popen,
@@ -23,49 +24,62 @@
23 order may be messed up if the command attempts to control order by24 order may be messed up if the command attempts to control order by
24 flushing stdout at points or setting it to unbuffered.25 flushing stdout at points or setting it to unbuffered.
2526
26
27 To test, we invoke both this method and this script with some commands27 To test, we invoke both this method and this script with some commands
28 and examine the output and exitvalue28 and examine the output and exit status.
2929
30 >>> python = sys.executable30 >>> python = sys.executable
3131
32 >>> def shhh_script(cmd):32 >>> def shhh_script(cmd):
33 ... from subprocess import Popen, PIPE33 ... from subprocess import Popen, PIPE
34 ... script = '%s %s' % (python, __file__)34 ... cmd = [python, __file__] + cmd
35 ... cmd = "%s '%s'" % (script, cmd)35 ... p = Popen(cmd, stdout=PIPE, stderr=PIPE)
36 ... p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
37 ... (out, err) = p.communicate()36 ... (out, err) = p.communicate()
38 ... return (out, err, p.returncode)37 ... return (out, err, p.returncode)
3938
40 >>> cmd = '''%s -c "import sys; sys.exit(%d)"''' % (python, 0)39 >>> cmd = [python, "-c", "import sys; sys.exit(0)"]
41 >>> shhh(cmd)40 >>> shhh(cmd)
42 041 0
43 >>> shhh_script(cmd)42 >>> shhh_script(cmd)
44 ('', '', 0)43 ('', '', 0)
4544
46 >>> cmd = '''%s -c "import sys; sys.exit(%d)"''' % (python, 1)45 >>> cmd = [python, "-c", "import sys; sys.exit(1)"]
47 >>> shhh(cmd)46 >>> shhh(cmd)
48 147 1
49 >>> shhh_script(cmd)48 >>> shhh_script(cmd)
50 ('', '', 1)49 ('', '', 1)
5150
52 >>> cmd = '''%s -c "import sys; print 666; sys.exit(%d)"''' % (51 >>> cmd = [python, "-c", "import sys; print 666; sys.exit(42)"]
53 ... python, 42)
54 >>> shhh(cmd)52 >>> shhh(cmd)
55 66653 666
56 4254 42
57 >>> shhh_script(cmd)55 >>> shhh_script(cmd)
58 ('666\n', '', 42)56 ('666\n', '', 42)
5957
60 >>> cmd = (58 >>> cmd = [
61 ... '''%s -c "import sys; print 666; '''59 ... python, "-c",
62 ... '''print >> sys.stderr, 667; sys.exit(42)"''' % python60 ... "import sys; print 666; print >> sys.stderr, 667; sys.exit(42)",
63 ... )61 ... ]
64 >>> shhh_script(cmd)62 >>> shhh_script(cmd)
65 ('666\n', '667\n', 42)63 ('666\n', '667\n', 42)
64
65 >>> cmd = ["TEST=sentinel value=0", "sh", "-c", 'echo "$TEST"; exit 1']
66 >>> shhh(cmd)
67 sentinel value=0
68 1
69 >>> shhh_script(cmd)
70 ('sentinel value=0\n', '', 1)
66 """71 """
6772
68 process = Popen(cmd, stdout=PIPE, stderr=PIPE, shell=True)73 env = dict(os.environ)
74 cmd = list(cmd)
75 while cmd:
76 if "=" in cmd[0]:
77 name, value = cmd[0].split("=", 1)
78 env[name] = value
79 del cmd[0]
80 else:
81 break
82 process = Popen(cmd, stdout=PIPE, stderr=PIPE, env=env)
69 (out, err) = process.communicate()83 (out, err) = process.communicate()
70 if process.returncode == 0:84 if process.returncode == 0:
71 return 085 return 0
@@ -76,6 +90,4 @@
7690
7791
78if __name__ == '__main__':92if __name__ == '__main__':
79 cmd = ' '.join(sys.argv[1:])93 sys.exit(shhh(sys.argv[1:]))
80 sys.exit(shhh(cmd))
81