subprocess.check_output failing with error 127

2019-05-07 10:02发布

问题:

I'm attempting to call an outside program from my python application, but it shows no output and fails with error 127. Executing the command from the command line works fine. (and I am in the correct working directory)

def buildContris (self, startUrl, reportArray):
    urls = []

    for row in reportArray:
        try:
            url = subprocess.check_output(["casperjs", "casper.js", startUrl, row[0]], shell=True)
            print (url)
            urls.append(url)
            break
        except subprocess.CalledProcessError as e:
            print ("Error: " + str(e.returncode) + " Output:" + e.output.decode())          

    return urls

Each loop outputs the following error: (I've also checked e.cmd. It's correct, but long, so I omitted it in this example)

Error: 127 Output: 

SOLUTION:

The following code works

app = subprocess.Popen(["./casperjs/bin/casperjs", "casper.js", startUrl, row[0]], stdout=subprocess.PIPE, stderr=subprocess.PIPE, env = {"PATH" : "/usr/local/bin/:/usr/bin"}, universal_newlines=True)
app.wait()
out, errs = app.communicate()

回答1:

Try adding the full path to casperjs in your subprocess.check_output() call.

Edit: Answeing your 2nd question. My apologies for the formatting as I'm on iPad. I think you should try Popen instead of check_output so that you can specify environment variables:

p = subprocess.Popen(["/path/to/casperjs", "casper.js", startUrl, row[0]], env={"PATH": "/path/to/phantomjs"})
url, err = p.communicate()


回答2:

shell=True changes the interpretation of the first argument (args) in check_output() call, from the docs:

On Unix with shell=True, ... If args is a sequence, the first item specifies the command string, and any additional items will be treated as additional arguments to the shell itself. That is to say, Popen does the equivalent of:

Popen(['/bin/sh', '-c', args[0], args[1], ...])

Exit status 127 might mean that the shell haven't found casperjs program or casperjs itself exited with that code.

To fix the code: drop shell=True and specify the full path to the casperjs program e.g.:

url = check_output(["./casperjs", "casper.js", startUrl, row[0]])


回答3:

Try to add explicitly the path in this way. If the file to call is in the same path (change __file__ if not):

cwd=os.path.dirname(os.path.realpath(__file__))
a  = subprocess.check_output(["./casper.js", startUrl, row[0]],cwd=cwd,shell=True)