Python subprocess.Popen to use git pager - python

I'm stuck at a point where I can't get my python subprocess call for "git show" to run though the core.pager.
In my ~/.gitconfig I have specified a core pager;
[core]
pager = cat -vet
And when I run this through subprocess (Popen or check_output)
cmd = ['git', '-C', repo, 'show', r'{0}:{1}'.format(commit, filename)]
stdout = subprocess.check_output(cmd)
The output I get have not run through the cat pager (the lines would end with '$')
When I run it myself from the cli, the output does go through the pager.
How should I do the call to subprocess to get the "git show" command to run through the core.pager?

AFAIK, git only post-process output through the configured pager when output is directed to a terminal. Since you are using subprocess.check_output, the output from git command is redirected to a pipe (to allow to give it to Python caller). As such core.pager is not called.
It you want to get a post-processed output, you will have to do it by hand
Assuming you want to use cat -vet as a post-processing filter, you could do:
cmd = ['git', '-C', repo, 'show', r'{0}:{1}'.format(commit, filename)]
p1 = subprocess.Popen(cmd, stdout = subprocess.PIPE)
filter = [ '/bin/cat', '-vet' ]
p2 = subprocess.Popen(filter, stdout = subprocess.PIPE, stdin = p1.stdout)
p2.wait()
stdout = p2.stdout.read()

Related

How to catch command line print output of git bash when calling from python?

Suppose I have 3 text files ours.txt, base.txt and theirs.txt and want to do a three way merge on them. When I call git merge-file -p ours.txt base.txt theirs.txt in Git Bash, it will print the merged text.
Whereas, when I run
import subprocess
dir = "path/to/text files"
cmd = ["git", "merge-file", "-p ", "ours.txt", "base.txt", "theirs.txt"]
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, cwd=dir)
I can access stdout and stderr through
(out, error) = p.communicate()
But can't seem to store the merged text that gets printed in Git Bash in a variable.
Does anybody have any ideas on how to retrieve it?
Thanks in advance.

access to file-output of external program

I'm trying to call a program from within Python that creates output and I want to work with this output when the external program has finished.
The programstring is
"sudo fing -r 1 > fingoutput.txt".
I managed to call the program with
from subprocess import call
cmd = ['sudo', 'fing', '-r 1']
call(cmd)
but I can't direct it's output to a file.
cmd = ['sudo', 'fing', '-r 1 > fingoutput.txt']
or
cmd = ['sudo', 'fing', '-r 1', '> fingoutput.txt']
produce
Error: multiple occurrences
I want to write the output to a file because it might be thousands of lines.
Thank you for your help,
Herbert.
You can use the stdout argument to redirect the output of your command to a file:
from subprocess import call
cmd = ['sudo', 'fing', '-r 1']
file_ = open('your_file.txt', 'w')
call(cmd, stdout=file_)
If you want to redirect to file from the shell-script itself you can always go for this
cmd = 'sudo fing -r 1 > fingoutput.txt'
call(cmd, shell=True)
Or
cmd = 'sudo fing -r 1 > fingoutput.txt'
p = Popen(cmd, shell=True, stdout=PIPE, stdin=PIPE)
Keeping shell=True may lead to security issues.

How to add options to python subprocess

I'm using Python 2.7.3.
I have a function that runs tesseract as a command line. Everything is working fine and now I would like to add a new parameter to the command -l rus (signifying russian language). Eventhough this works on my commandline, it doesn't seem to work from Python.
Command line:
$ /usr/local/bin/tesseract /Users/anthony/Downloads/rus.png outfile -l rus && more outfile.txt
Tesseract Open Source OCR Engine v3.02.02 with Leptonica
Полу-Милорд, полу-купец,
Полу-мудрец, полу-невежда,
Полу-подлец, но есть надежда,
Что будет полным наконец.
Python function
def ocr(self,path):
path = "/Users/anthony/Downloads/rus.png"
process = subprocess.Popen(['/usr/local/bin/tesseract', path,'outfile','-l rus'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
out, err = process.communicate()
print err
print out
with open('outfile.txt', 'r') as handle:
contents = handle.read()
os.remove(temp.name + '.txt')
os.remove(temp.name)
return contents, out
the above returns "HOIIY nony HOIIY nony Hony no ecTb HHJICXQRI 6y11e" which suggests that the -l rus flag is being ignored.
Question
How can I execute the following command as a python subprocess?
/usr/local/bin/tesseract /Users/anthony/Downloads/rus.png outfile -l rus
You need to split the '-l rus' argument to two separate ones to make sure it's parsed correctly by the program:
process = subprocess.Popen(
['/usr/local/bin/tesseract', path, 'outfile', '-l', 'rus'],
stdout=subprocess.PIPE, stderr=subprocess.STDOUT
)
It might be handy to use str.split() or shlex.split() for this:
cmd = '/usr/local/bin/tesseract /Users/anthony/Downloads/rus.png outfile -l rus'
process = subprocess.Popen(
cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.STDOUT
)
process = subprocess.Popen('/usr/local/bin/tesseract '+path+' outfile -l rus', stdout=subprocess.PIPE, stderr=subprocess.STDOUT,shell=True)
You can run it with shell=True.

How to print the output of shell instantly by python script

I executed some commands in shell with python. I need to show the command response in shell. But the commands will execute 10s . I need to wait. How can I show the echo of the commands instantly. Following is my code
cmd = "commands"
output = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
print(output.stdout.read())
And I need to use the output of the command. so I can't use subprocess.call
Read from output.stdout in a loop:
cmd = "commands"
output = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
for line in output.stdout:
print(line)
edit: seems then in python2 this still doesn't work in evey case, but this will:
for line in iter(output.stdout.readline, ''):
print(line)

popen command not giving required output

I am using the below code to run a git command "git tag -l contains ad0beef66e5890cde6f0961ed03d8bc7e3defc63" ..if I run this command standalone I see the required output..but through the below program,it doesnt work,does anyone have any inputs on what could be wrong?
from subprocess import check_call,Popen,PIPE
revtext = "ad0beef66e5890cde6f0961ed03d8bc7e3defc63"
proc = Popen(['git', 'tag', '-l', '--contains', revtext ],stdout=PIPE ,stderr=PIPE)
(out, error) = proc.communicate()
print "OUT"
print out

Categories

Resources