OSError – Failed to execute command

Playing a  bit with Jython lately.

As in other programming languages & scripting tools needed to invoke another Application.  Be it another script or Application, one occasionally needs to spawn another stand-alone app:

So looked at some sample code and ended up with something resembling

import sys
import os
import tempfile
import popen2
script_contents = 'Echo "Hello World"' 
script_file = tempfile.mktemp('.cmd')
file = open(script_file, 'w')
file.write(script_contents)
file.close()

command = r'"%s"' % script_file 

proc = popen2.Popen3(command, True)
proc.tochild.close()
output = proc.fromchild.read()
errors = proc.childerr.read()
status = proc.wait()

print '[DEBUG] OUTPUT: %s' % output
print '[DEBUG] ERRORS: %s' % errors
print '[DEBUG] RETURN CODE: %s' % status

if os.path.isfile(script_file):
    os.remove(script_file)

Though, the above script is a bit watered-down it basically does the following:

  1. Dynamically generates a payload
  2. Creates a temporary file
  3. Saves the generated payload unto the temporary file
  4. Invokes the Temp file
  5. Cleans-up by removing the temp file

As I tried running the app kept getting an error that resembles the error listed below:

Failed to get environment, environ will be empty: (0, 'Failed to execute command 
([\'sh\', \'-c\', \'env\']): java.io.IOException: Cannot run 
program "sh": CreateProcess error=2, The system cannot find the file specified')

script_file name is: e:\temp\tempfile.cmd

Traceback (innermost last):

File "C:\Windows\TEMP\eqscript1323213519948", line 41, in ?

File "E:\Program Files (x86)\jython\Lib\popen2.py", line 72, in __init__

File "E:\Program Files (x86)\jython\Lib\javashell.py", line 64, in execute

OSError: (0, 'Failed to execute command ([\'sh\', \'-c\', "e:\\\\temp\\\\tempfile.cmd"\']): java.io.IOException: Cannot run program "sh": CreateProcess error=2, The system cannot find the file specified')

Had a bit of difficulty understanding the problem:

  1. Was the system having difficulty determining the temporary folder
  2. Did we not have access to the temporary folder

To get a bit closer to what was happening behind the scene, commented out the bit of code that was removing the script file:

Doing so allowed us to preserve the payload and execute the payload file directly (against the OS).

if os.path.isfile(script_file):
    os.remove(script_file)

Ended up the at the same place \ space:

Could not execute due to file not found.

More goggling brought us joy.  The problem is that sometimes one has to explicitly specify the OS.

The clue came from:

Jython – javaos.getenv() gives “Failed to get environment, environ will be empty”
http://stackoverflow.com/questions/245787/jython-javaos-getenv-gives-failed-to-get-environment-environ-will-be-empty

Try to uncomment and change the os setting in the 'registry' file

(it is in the same directory as your jython.jar / i hope)

# python.os determines operating-specific features, similar to and overriding the
# Java property "os.name".
# Some generic values are also supported: 'nt', 'ce' and 'posix'.
# Uncomment the following line for the most generic OS behavior available.
#python.os=None
python.os=nt
# try nt or dos

Once we knew we had to deal with the registry file the next question is what is actual name of the registry file, where should it be placed, what determines where the system looks for it:

The easiest path would have being to go back and read the Language’s documentation, but as always took the laziest path. Googled for it:

Found some help along the way via:

  1. “Failed to execute command ([\’sh\’, \’-c\’, \’env\’]): java.io.IOException: Cannot run program “sh”: CreateProcess error=2, The system cannot find the file specified.”
    http://www-01.ibm.com/support/docview.wss?uid=swg21411513

The registry file:

  1. The name of the registry file is registry
  2. Review our jython is invoked – In our case jython.bat and make a note of any arguments passed in or initialized

In our case, we created a file named registry and added this lone line:

python.os=nt

Things worked well once we explicitly specified that our OS is Windows.

It is probably that by default the OS is Unix.

But, as Billy Currington said, thank God for good directions, on my way back home, went back (after the fact) and read the Jython’s FAQ:

http://jython.org/archive/22/userfaq.html#where-s-the-registry-file

The location and name of the registry was a bit clearer:

Jython FAQ
http://jython.org/archive/22/userfaq.html#where-s-the-registry-file

Where’s the registry file?
Jython’s installation includes a file called “registry” that you will find in the root directory of the Jython installation (e.g. /usr/local/jython or c:jython).

At initialization, Jython searches for the “registry” file in the directory specified by the “python.home” property, or the “.jython” file in the user’s home directory.

The “python.home” property is often set in the startup with Java’s -D switch. The shell script that starts Jython (jython.bat or jython) demonstrates the use of the -D switch to set the “python.home” property. When embedding Jython, it is often still best to use the -D switch because the -D properties appear in System.getProperties(), which is usually the “preProperties” (first arg) in the static PythonInterpreter.initialize method. With python.home in the preProperties, the interpreter successfully loads preProperties, registry properties, and postProperties (the second arg to initialize) in the correct order.

If you wish to use your home directory, and do not know where your home directory is, don’t worry- Jython knows:

>>> print java.lang.System.getProperty
     ("user.home")

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s