Python error when using os.popen() - python

Well, I have a python script running on Mac OS X. Now I need to modify it to support updating my SVN working copy into a specified time. However, after learning I've found that SVN commands only support updating the working copy into a specified version.
So I write a function to grub the information from the command: svn log XXX, to find the corresponding version to the specified time. Here is my solution:
process=os.popen('svn log XXX')
print process.readline()
print process.readline()
process.close()
To make the problem simple, I just print the first 2 lines in the output. However, when I was executing the script, I got the error message: svn: Write error: Broken pipe
I think that the reason why I got the message is that the svn command kept executing when I was closing the Popen. So the error message arise.
Is there any one who can help me slove the problem? Or give me a alternative solution to reach the goal. Thx!

I get that error whenever I use svn log | head, too, it's not Python specific. Try something like:
from subprocess import PIPE, Popen
process = Popen('svn log XXX', stdout=PIPE, stderr=PIPE)
print process.stdout.readline()
print process.stdout.readline()
to suppress the stderr. You could also just use
stdout, stderr = Popen('svn log XXX | head -n2', stdout=PIPE, stderr=PIPE, shell=True).communicate()
print stdout

Please use pysvn. It is quite easy to use. Or use subprocess.
Does you error still occur if you do finally:
print process.read()
And it is better to call wait() if you use os.popen or subprocess.

Related

How can python subprocess honour powershell exit code?

I have in my root directory
$ cat pssa.py
import subprocess,sys
p = subprocess.Popen(["powershell.exe",".\\pre-commit.ps1"],
stdout=sys.stdout,stderr=sys.stderr,shell=True)
p.communicate()
pre-commit.ps1 returns 1, so it's in error, but
python pssa.py
returns 0.
Forgive us the complete lack of python skills, but I'm stuck. Grateful for help suggesting how python pssa.py can return the error code from the powershell script.
I think I read somewhere Popen does not wait for the script to finish. So 1) is there another method I can use that does wait, and in turn can read the return code from powershell?
Python is installed on Windows. The idea with above is to be able to use, for example, pre-commit run meaningfully on Windows. Right now, pre-commit run, executes the powershell script but does not fail as I would like it to.
Popen.communicate waits for a subprocess to finish and fills the returncode in Popen. You can use it like this:
import subprocess, sys
p = subprocess.Popen(["powershell.exe",".\\pre-commit.ps1"],
stdout=sys.stdout,stderr=sys.stderr,shell=True)
outs, errs = p.communicate()
code = p.returncode

python output from subprocess.Popen

I'm trying to write a simple software to scan some bluetooth devices (beacon with advertising) and I have a problem with the instruction subprocess.Popen
p1 = subprocess.Popen(['timeout','10s','hcitool','lescan'],stdout=subprocess.PIPE,stderr=subprocess.PIPE)
p1.wait()
output, error = p1.communicate()
print("stdout: {}".format(output))
print("stderr: {}".format(error))
the output and error variables are empty!
If I remove the stdout=subprocess.PIPE,stderr=subprocess.PIPE from the Popen I can see the right result in the console, if I change the command with ['ls','-l'] it works fine and I see the result in the variables .
I've tryed with subprocess.run (with the timeout) and it is the same.
If I don't use the timeout obviously the command never ends.
I can't use pybluez and my python version is the 3.7
Can someone help me?
Solved using ['timeout','-s','INT','10s','hcitool','lescan'] as command instead of ['timeout','10s','hcitool','lescan'].
Maybe in the second case the process was not killed well and I didn't receive the output.
Thank you the same.

How to debug code run using Popen in Pycharm

I am running a codebase I have inherited from someone else which makes extensive use of user input. For this reason I am running it using subprocess.Popen. Here is an example. The following script (caller.py) calls the third-party code.
from subprocess import Popen, PIPE, STDOUT
import sys
user_input = ['John', '555']
communicate_argument = '\n'.join(user_input)
p = Popen([sys.executable, 'example2.py'], stdout=PIPE, stdin=PIPE, stderr=STDOUT, encoding='utf-8')
stdout, stderr = p.communicate(communicate_argument)
print(stdout)
The following script (example.py) emulates behavior of the source code I was provided, by accepting a couple of input arguments from the user:
name = input('What is your name\n')
age = input('What is your age\n')
print('You are {}, and you are {} years old'.format(name, age))
Running the code works fine, and I get the expected output.
Debugging the code partially works, but partially doesn't. The debugger successfully attaches to the child process p such that any breakpoints placed in example.py will work. However it seems that the debug console does not successfully attached to the child process. When I try to enter some variables in the debug console, they do not print out, even if they appear as active variables in my debug session.
EDIT
It turns out this might be a bug. I have asked the same question in pycharm's official forum and they made an issue out of it:
https://intellij-support.jetbrains.com/hc/en-us/community/posts/360009571680-Debugging-code-run-through-subprocess-Popen
So I guess what I'd be looking for is an effective workaround which would allow me to use a regular python interpreter in combination with the debugger to inspect and run operations on variables.
I have had a similar issue with python and docker logs. What solved was running python with the -u flag as described here. Perhaps try changing your Popen call to use python and then include the -u flag. e.g. Popen(["python", "-u", "example2.py"], stdout=PIPE, stdin=PIPE, stderr=STDOUT, encoding='utf-8')

Using subprocess to call R from Python, want to keep STDOUT and ignore STDERR

So this code in Python that I have currently works in returning my STDOUT in the variable "run":
run = subprocess.check_output(['Rscript','runData.R',meth,expr,norm])
But it still prints to the screen all this ugly text from having to install a package in R, etc, etc. So I would like for that to be ignored and sent into STDERR. Is there any way to do this? This is what I'm currently working on but it doesn't seem to work. Again, I just want it to ignore what it is printing to the screen except the results. So I want to ignore STDERR and keep STDOUT. Thank you!
run = subprocess.Popen(['Rscript','runData.R',meth,expr,norm],shell=False, stdout=subprocess.PIPE,stderr=devnull)
To avoid piping stderr entirely you may redirect it to os.devnull:
os.devnull
The file path of the null device. For example: '/dev/null' for POSIX, 'nul' for Windows. Also available via os.path.
import os
import subprocess
with open(os.devnull) as devnull:
subprocess.Popen([cmd arg], stdout=subprocess.PIPE, stderr=devnull)
I actually solved my problem as soon as I posted this! My apologies! This is how it worked:
output = subprocess.Popen(['Rscript','runData.R',meth,expr,norm],shell=False, stdout=subprocess.PIPE,stderr=subprocess.PIPE)
final = output.stdout.read()
This ignored the messy stuff from the command line and saved my results into final.
Thank you for everyone's quick replies!

Directly connect system call output to logger in Python

I'm writing some code which involves running a few shell commands from Python and ideally, I would like to integrate the output from these commands into the logger that I'm using. I know I can divert stdout into a file / socket as follows:
call( '<a-shell-cmd>', shell=True, stdout=myFile )
but I'd rather not have the bind of opening a temporary file, looping over the file writing the output, closing the file, deleting the file etc. If there's anyway that I can send the output directly to the logger, it would seem a lot neater to me. Any ideas?
Use the subprocess module.
Tip: you can go to the documentation for a particular version of python via http://docs.python.org/release/<major>.<minor>/
From Python 2.7 and above:
output = subprocess.check_output(["command", "arg1"], shell=True)
In Python 2.4:
process = subprocess.Popen(["command", "arg1"], shell=True, stdout=subprocess.PIPE)
stdout,stderr = process.communicate()
# not shown: how to use Popen.poll() to wait for process death.
# while filling an output buffer
print stdout
Below Python 2.4:
output = os.popen('ls')
Use os.popen
output = os.popen('ls')
You can then log output or do it directly when calling the above.

Categories

Resources