Show More
@@ -731,16 +731,12 b" _assign_system_re = re.compile(r'(?P<lhs>(\\s*)([\\w\\.]+)((\\s*,\\s*[\\w\\.]+)*))'" | |||||
731 |
|
731 | |||
732 | def transform_assign_system(line): |
|
732 | def transform_assign_system(line): | |
733 | """Handle the `files = !ls` syntax.""" |
|
733 | """Handle the `files = !ls` syntax.""" | |
734 | # FIXME: This transforms the line to use %sc, but we've listed that magic |
|
|||
735 | # as deprecated. We should then implement this functionality in a |
|
|||
736 | # standalone api that we can transform to, without going through a |
|
|||
737 | # deprecated magic. |
|
|||
738 | m = _assign_system_re.match(line) |
|
734 | m = _assign_system_re.match(line) | |
739 | if m is not None: |
|
735 | if m is not None: | |
740 | cmd = m.group('cmd') |
|
736 | cmd = m.group('cmd') | |
741 | lhs = m.group('lhs') |
|
737 | lhs = m.group('lhs') | |
742 |
expr = make_quoted_expr( |
|
738 | expr = make_quoted_expr(cmd) | |
743 |
new_line = '%s = get_ipython(). |
|
739 | new_line = '%s = get_ipython().getoutput(%s)' % (lhs, expr) | |
744 | return new_line |
|
740 | return new_line | |
745 | return line |
|
741 | return line | |
746 |
|
742 |
@@ -63,7 +63,7 b' from IPython.utils.path import get_home_dir, get_ipython_dir, HomeDirError' | |||||
63 | from IPython.utils.process import system, getoutput |
|
63 | from IPython.utils.process import system, getoutput | |
64 | from IPython.utils.strdispatch import StrDispatch |
|
64 | from IPython.utils.strdispatch import StrDispatch | |
65 | from IPython.utils.syspathcontext import prepended_to_syspath |
|
65 | from IPython.utils.syspathcontext import prepended_to_syspath | |
66 | from IPython.utils.text import num_ini_spaces, format_screen |
|
66 | from IPython.utils.text import num_ini_spaces, format_screen, LSString, SList | |
67 | from IPython.utils.traitlets import (Int, Str, CBool, CaselessStrEnum, Enum, |
|
67 | from IPython.utils.traitlets import (Int, Str, CBool, CaselessStrEnum, Enum, | |
68 | List, Unicode, Instance, Type) |
|
68 | List, Unicode, Instance, Type) | |
69 | from IPython.utils.warn import warn, error, fatal |
|
69 | from IPython.utils.warn import warn, error, fatal | |
@@ -1847,7 +1847,14 b' class InteractiveShell(Configurable, Magic):' | |||||
1847 | #------------------------------------------------------------------------- |
|
1847 | #------------------------------------------------------------------------- | |
1848 |
|
1848 | |||
1849 | def system(self, cmd): |
|
1849 | def system(self, cmd): | |
1850 |
"""Call the given cmd in a subprocess. |
|
1850 | """Call the given cmd in a subprocess. | |
|
1851 | ||||
|
1852 | Parameters | |||
|
1853 | ---------- | |||
|
1854 | cmd : str | |||
|
1855 | Command to execute (can not end in '&', as bacground processes are | |||
|
1856 | not supported. | |||
|
1857 | """ | |||
1851 | # We do not support backgrounding processes because we either use |
|
1858 | # We do not support backgrounding processes because we either use | |
1852 | # pexpect or pipes to read from. Users can always just call |
|
1859 | # pexpect or pipes to read from. Users can always just call | |
1853 | # os.system() if they really want a background process. |
|
1860 | # os.system() if they really want a background process. | |
@@ -1856,11 +1863,30 b' class InteractiveShell(Configurable, Magic):' | |||||
1856 |
|
1863 | |||
1857 | return system(self.var_expand(cmd, depth=2)) |
|
1864 | return system(self.var_expand(cmd, depth=2)) | |
1858 |
|
1865 | |||
1859 | def getoutput(self, cmd): |
|
1866 | def getoutput(self, cmd, split=True): | |
1860 |
"""Get output (possibly including stderr) from a subprocess. |
|
1867 | """Get output (possibly including stderr) from a subprocess. | |
|
1868 | ||||
|
1869 | Parameters | |||
|
1870 | ---------- | |||
|
1871 | cmd : str | |||
|
1872 | Command to execute (can not end in '&', as bacground processes are | |||
|
1873 | not supported. | |||
|
1874 | split : bool, optional | |||
|
1875 | ||||
|
1876 | If True, split the output into an IPython SList. Otherwise, an | |||
|
1877 | IPython LSString is returned. These are objects similar to normal | |||
|
1878 | lists and strings, with a few convenience attributes for easier | |||
|
1879 | manipulation of line-based output. You can use '?' on them for | |||
|
1880 | details. | |||
|
1881 | """ | |||
1861 | if cmd.endswith('&'): |
|
1882 | if cmd.endswith('&'): | |
1862 | raise OSError("Background processes not supported.") |
|
1883 | raise OSError("Background processes not supported.") | |
1863 |
|
|
1884 | out = getoutput(self.var_expand(cmd, depth=2)) | |
|
1885 | if split: | |||
|
1886 | out = SList(out.splitlines()) | |||
|
1887 | else: | |||
|
1888 | out = LSString(out) | |||
|
1889 | return out | |||
1864 |
|
1890 | |||
1865 | #------------------------------------------------------------------------- |
|
1891 | #------------------------------------------------------------------------- | |
1866 | # Things related to aliases |
|
1892 | # Things related to aliases |
@@ -2919,7 +2919,7 b' Defaulting color scheme to \'NoColor\'"""' | |||||
2919 | # If all looks ok, proceed |
|
2919 | # If all looks ok, proceed | |
2920 | out = self.shell.getoutput(cmd) |
|
2920 | out = self.shell.getoutput(cmd) | |
2921 | if opts.has_key('l'): |
|
2921 | if opts.has_key('l'): | |
2922 |
out = SList(out.split( |
|
2922 | out = SList(out.splitlines()) | |
2923 | else: |
|
2923 | else: | |
2924 | out = LSString(out) |
|
2924 | out = LSString(out) | |
2925 | if opts.has_key('v'): |
|
2925 | if opts.has_key('v'): |
@@ -486,7 +486,7 b' class AssignSystemTransformer(PrefilterTransformer):' | |||||
486 | if m is not None: |
|
486 | if m is not None: | |
487 | cmd = m.group('cmd') |
|
487 | cmd = m.group('cmd') | |
488 | lhs = m.group('lhs') |
|
488 | lhs = m.group('lhs') | |
489 |
expr = make_quoted_expr("sc |
|
489 | expr = make_quoted_expr("sc =%s" % cmd) | |
490 | new_line = '%s = get_ipython().magic(%s)' % (lhs, expr) |
|
490 | new_line = '%s = get_ipython().magic(%s)' % (lhs, expr) | |
491 | return new_line |
|
491 | return new_line | |
492 | return line |
|
492 | return line |
@@ -395,8 +395,8 b' def transform_checker(tests, func):' | |||||
395 |
|
395 | |||
396 | syntax = \ |
|
396 | syntax = \ | |
397 | dict(assign_system = |
|
397 | dict(assign_system = | |
398 |
[('a =! ls', 'a = get_ipython(). |
|
398 | [('a =! ls', 'a = get_ipython().getoutput("ls")'), | |
399 |
('b = !ls', 'b = get_ipython(). |
|
399 | ('b = !ls', 'b = get_ipython().getoutput("ls")'), | |
400 | ('x=1', 'x=1'), # normal input is unmodified |
|
400 | ('x=1', 'x=1'), # normal input is unmodified | |
401 | (' ',' '), # blank lines are kept intact |
|
401 | (' ',' '), # blank lines are kept intact | |
402 | ], |
|
402 | ], |
@@ -99,6 +99,27 b' def process_handler(cmd, callback, stderr=subprocess.PIPE):' | |||||
99 | return out |
|
99 | return out | |
100 |
|
100 | |||
101 |
|
101 | |||
|
102 | def getoutput(cmd): | |||
|
103 | """Return standard output of executing cmd in a shell. | |||
|
104 | ||||
|
105 | Accepts the same arguments as os.system(). | |||
|
106 | ||||
|
107 | Parameters | |||
|
108 | ---------- | |||
|
109 | cmd : str | |||
|
110 | A command to be executed in the system shell. | |||
|
111 | ||||
|
112 | Returns | |||
|
113 | ------- | |||
|
114 | stdout : str | |||
|
115 | """ | |||
|
116 | ||||
|
117 | out = process_handler(cmd, lambda p: p.communicate()[0], subprocess.STDOUT) | |||
|
118 | if out is None: | |||
|
119 | out = '' | |||
|
120 | return out | |||
|
121 | ||||
|
122 | ||||
102 | def getoutputerror(cmd): |
|
123 | def getoutputerror(cmd): | |
103 | """Return (standard output, standard error) of executing cmd in a shell. |
|
124 | """Return (standard output, standard error) of executing cmd in a shell. | |
104 |
|
125 |
@@ -29,6 +29,7 b' except ImportError:' | |||||
29 |
|
29 | |||
30 | # Our own |
|
30 | # Our own | |
31 | from .autoattr import auto_attr |
|
31 | from .autoattr import auto_attr | |
|
32 | from ._process_common import getoutput | |||
32 |
|
33 | |||
33 | #----------------------------------------------------------------------------- |
|
34 | #----------------------------------------------------------------------------- | |
34 | # Function definitions |
|
35 | # Function definitions | |
@@ -97,6 +98,28 b' class ProcessHandler(object):' | |||||
97 | except KeyboardInterrupt: |
|
98 | except KeyboardInterrupt: | |
98 | print('^C', file=sys.stderr, end='') |
|
99 | print('^C', file=sys.stderr, end='') | |
99 |
|
100 | |||
|
101 | def getoutput_pexpect(self, cmd): | |||
|
102 | """Run a command and return its stdout/stderr as a string. | |||
|
103 | ||||
|
104 | Parameters | |||
|
105 | ---------- | |||
|
106 | cmd : str | |||
|
107 | A command to be executed in the system shell. | |||
|
108 | ||||
|
109 | Returns | |||
|
110 | ------- | |||
|
111 | output : str | |||
|
112 | A string containing the combination of stdout and stderr from the | |||
|
113 | subprocess, in whatever order the subprocess originally wrote to its | |||
|
114 | file descriptors (so the order of the information in this string is the | |||
|
115 | correct order as would be seen if running the command in a terminal). | |||
|
116 | """ | |||
|
117 | pcmd = self._make_cmd(cmd) | |||
|
118 | try: | |||
|
119 | return pexpect.run(pcmd).replace('\r\n', '\n') | |||
|
120 | except KeyboardInterrupt: | |||
|
121 | print('^C', file=sys.stderr, end='') | |||
|
122 | ||||
100 | def system(self, cmd): |
|
123 | def system(self, cmd): | |
101 | """Execute a command in a subshell. |
|
124 | """Execute a command in a subshell. | |
102 |
|
125 | |||
@@ -161,9 +184,9 b' class ProcessHandler(object):' | |||||
161 | return '%s -c "%s"' % (self.sh, cmd) |
|
184 | return '%s -c "%s"' % (self.sh, cmd) | |
162 |
|
185 | |||
163 |
|
186 | |||
164 |
|
187 | # Make system() with a functional interface for outside use. Note that we use | ||
165 | # Make objects with a functional interface for outside use |
|
188 | # getoutput() from the _common utils, which is built on top of popen(). Using | |
166 | __ph = ProcessHandler() |
|
189 | # pexpect to get subprocess output produces difficult to parse output, since | |
167 |
|
190 | # programs think they are talking to a tty and produce highly formatted output | ||
168 | system = __ph.system |
|
191 | # (ls is a good example) that makes them hard. | |
169 | getoutput = __ph.getoutput |
|
192 | system = ProcessHandler().system |
General Comments 0
You need to be logged in to leave comments.
Login now