Samuel Dauzon
Samuel Dauzon

Reputation: 11334

Get all output of bash command in Python

I have a Python scrit which let me to check PHP file syntax.

I use subprocess.check_output command to call a bash command but it returns me only half of the response displayed.

The check_php.py file :

#!/usr/bin/python
# coding:utf-8
import os
import sys
import subprocess
import argparse
import fnmatch
import ntpath

path_base = os.path.dirname(os.path.realpath(__file__))

parser = argparse.ArgumentParser(
    description="This command checks the PHP syntaxe of files"
)
parser.add_argument('--path', '-p',
    help="Path for .php searching"
)
parser.add_argument('--file', '-f',
    help="Path of file to check"
)
args = parser.parse_args()

def check_php_file(path_file):
    command = 'php -l '+path_file
    sortie = ''
    try:
        sortie = subprocess.check_output(command, shell=True)
    except Exception as e:
        sortie = str(e)
    return sortie

if args.path:
    if args.path.startswith('/') or args.path.startswith('~'):
        path_base = args.path
    else:
        path_base = os.path.join(path_base, args.path)

if args.file:
    if args.file.startswith('/') or args.file.startswith('~'):
        path_file = args.path
    else:
        path_file = os.path.join(path_base, args.file)
    response = check_php_file(path_file)
    print("_____"+response+"_____")

The checking.php file (with a syntax error) :

<?php
if (true {
    echo "True";
}

The command to check PHP file :

python check_php.py -f checking.php

The output displayed after command :

PHP Parse error:  syntax error, unexpected '{' in /home/jedema/checking.php on line 3
_____Command 'php -l /home/jedema/checking.php' returned non-zero exit status 255_____

So, my Python code can handle the following response :

Command 'php -l /home/jedema/checking.php' returned non-zero exit status 255

But I want also get in a String the following response :

PHP Parse error:  syntax error, unexpected '{' in /home/jedema/checking.php on line 3

Do you have any idea to get the full response ?

Edit I have already read the following question : Get bash output with python

Solution (inspired by Salo answer)

Install Sh :

pip install sh

It works by adding these imports :

import sh

Then, With this check_php_file_method :

def check_php_file(path_file):
    sortie = ''
    try:
        sortie = sh.php('-l', path_file)
    except sh.ErrorReturnCode_255 as e:
        sortie = format(e.stderr)
    return sortie

Upvotes: 1

Views: 1742

Answers (2)

Salo
Salo

Reputation: 2126

I would use sh for such needs. An example:

If I have a script that returns a non-zero return code and prints something on stderr like this (named test_external_command.sh):

#!/bin/bash
>&2 echo "my Error on STDERR!"
exit 255

And I want to have the stderr in a variable I can use the sh module in a Python script as follows (named checker.py):

import sh

def main():
    my_cmd = sh.Command('/path/to/test_external_command.sh')
    try:
        my_cmd()
    except sh.ErrorReturnCode_255 as e:
        print 'expected return code'
        print 'STDERR was: {}'.format(e.stderr)


if __name__ == '__main__':
    main()

You can see that the stderr is saved in sh.ErrorReturnCode_255 as the stderr attribute.

Hope this helps!

Upvotes: 2

Hackaholic
Hackaholic

Reputation: 19763

Use subprocess.Popen, its returns tuple of output and error

child = subprocess.Popen(['php','-l', path_file], stdout=subprocess.PIPE, shell=True)
output, error = child.communicate()

Upvotes: 1

Related Questions