| Tor Norbye | 3a2425a | 2013-11-04 10:16:08 -0800 | [diff] [blame^] | 1 | """ |
| 2 | Implement subshell functionality for Jython. |
| 3 | |
| 4 | This is mostly to provide the environ object for the os module, |
| 5 | and subshell execution functionality for os.system and popen* functions. |
| 6 | |
| 7 | javashell attempts to determine a suitable command shell for the host |
| 8 | operating system, and uses that shell to determine environment variables |
| 9 | and to provide subshell execution functionality. |
| 10 | """ |
| 11 | from java.lang import System, Runtime |
| 12 | from java.io import File |
| 13 | from java.io import IOException |
| 14 | from java.io import InputStreamReader |
| 15 | from java.io import BufferedReader |
| 16 | from UserDict import UserDict |
| 17 | import jarray |
| 18 | import os |
| 19 | import string |
| 20 | import subprocess |
| 21 | import sys |
| 22 | import types |
| 23 | import warnings |
| 24 | warnings.warn('The javashell module is deprecated. Use the subprocess module.', |
| 25 | DeprecationWarning, 2) |
| 26 | |
| 27 | __all__ = ["shellexecute"] |
| 28 | |
| 29 | def __warn( *args ): |
| 30 | print " ".join( [str( arg ) for arg in args ]) |
| 31 | |
| 32 | class _ShellEnv: |
| 33 | """Provide environment derived by spawning a subshell and parsing its |
| 34 | environment. Also supports subshell execution functions and provides |
| 35 | empty environment support for platforms with unknown shell functionality. |
| 36 | """ |
| 37 | def __init__( self, cmd=None, getEnv=None, keyTransform=None ): |
| 38 | """Construct _ShellEnv instance. |
| 39 | cmd: list of exec() arguments required to run a command in |
| 40 | subshell, or None |
| 41 | getEnv: shell command to list environment variables, or None. |
| 42 | deprecated |
| 43 | keyTransform: normalization function for environment keys, |
| 44 | such as 'string.upper', or None. deprecated. |
| 45 | """ |
| 46 | self.cmd = cmd |
| 47 | self.environment = os.environ |
| 48 | |
| 49 | def execute( self, cmd ): |
| 50 | """Execute cmd in a shell, and return the java.lang.Process instance. |
| 51 | Accepts either a string command to be executed in a shell, |
| 52 | or a sequence of [executable, args...]. |
| 53 | """ |
| 54 | shellCmd = self._formatCmd( cmd ) |
| 55 | |
| 56 | env = self._formatEnvironment( self.environment ) |
| 57 | try: |
| 58 | p = Runtime.getRuntime().exec( shellCmd, env, File(os.getcwd()) ) |
| 59 | return p |
| 60 | except IOException, ex: |
| 61 | raise OSError( |
| 62 | 0, |
| 63 | "Failed to execute command (%s): %s" % ( shellCmd, ex ) |
| 64 | ) |
| 65 | |
| 66 | ########## utility methods |
| 67 | def _formatCmd( self, cmd ): |
| 68 | """Format a command for execution in a shell.""" |
| 69 | if self.cmd is None: |
| 70 | msgFmt = "Unable to execute commands in subshell because shell" \ |
| 71 | " functionality not implemented for OS %s" \ |
| 72 | " Failed command=%s" |
| 73 | raise OSError( 0, msgFmt % ( os._name, cmd )) |
| 74 | |
| 75 | if isinstance(cmd, basestring): |
| 76 | shellCmd = self.cmd + [cmd] |
| 77 | else: |
| 78 | shellCmd = cmd |
| 79 | |
| 80 | return shellCmd |
| 81 | |
| 82 | def _formatEnvironment( self, env ): |
| 83 | """Format enviroment in lines suitable for Runtime.exec""" |
| 84 | lines = [] |
| 85 | for keyValue in env.items(): |
| 86 | lines.append( "%s=%s" % keyValue ) |
| 87 | return lines |
| 88 | |
| 89 | def _getOsType(): |
| 90 | return os._name |
| 91 | |
| 92 | _shellEnv = _ShellEnv(subprocess._shell_command) |
| 93 | shellexecute = _shellEnv.execute |