'str' object has no attribute 'fileno' - python

I want to open git bash and write git commands into it.
I used following code:
from subprocess import Popen, PIPE
process = subprocess.run(['D:\\casdev\\SmartGit\\git\\git-bash.exe'],shell= "True", bufsize=0,stdin="git status",stdout=PIPE, stderr=PIPE, encoding="UTF8")
stdoutput, stderroutput = process.communicate()
response=process.stdout.read()
Output:
runfile('C:/Users/uib25171/Desktop/MiniProject/Trials/untitled3.py', wdir='C:/Users/uib25171/Desktop/MiniProject/Trials')
Traceback (most recent call last):
File "<ipython-input-66-00c2c0a9827c>", line 1, in <module>
runfile('C:/Users/uib25171/Desktop/MiniProject/Trials/untitled3.py', wdir='C:/Users/uib25171/Desktop/MiniProject/Trials')
File "C:\Users\uib25171\AppData\Local\Continuum\anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 827, in runfile
execfile(filename, namespace)
File "C:\Users\uib25171\AppData\Local\Continuum\anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 110, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)
File "C:/Users/uib25171/Desktop/MiniProject/Trials/untitled3.py", line 37, in <module>
process = subprocess.run(['D:\\casdev\\SmartGit\\git\\git-bash.exe'],shell= "True", bufsize=0,stdin="git status",stdout=PIPE, stderr=PIPE, encoding="UTF8")
File "C:\Users\uib25171\AppData\Local\Continuum\anaconda3\lib\subprocess.py", line 472, in run
with Popen(*popenargs, **kwargs) as process:
File "C:\Users\uib25171\AppData\Local\Continuum\anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 143, in __init__
super(SubprocessPopen, self).__init__(*args, **kwargs)
File "C:\Users\uib25171\AppData\Local\Continuum\anaconda3\lib\subprocess.py", line 728, in __init__
errread, errwrite) = self._get_handles(stdin, stdout, stderr)
File "C:\Users\uib25171\AppData\Local\Continuum\anaconda3\lib\subprocess.py", line 1039, in _get_handles
p2cread = msvcrt.get_osfhandle(stdin.fileno())
**AttributeError: 'str' object has no attribute 'fileno'**
Can somebody help me?

It seems as if your passing a string instead of an input stream at stdin="git status"

You are mixing stdin, which should be a filehandle, with input, which lets you pass a string as input to your subprocess. But more fundamentally, you are mixing apples and oranges. communicate makes sense for a bare Popen object, but that's not what subprocess.run returns. The output from your command is simpy process.stdout.
But really you should probably be running
process = subprocess.run(['git', 'status'],
text=True, encoding="UTF8", capture=True)
response = process.stdout
If you need shell=True (which you don't here) you can pass the path to Bash in the executable= keyword parameter.

You messed up your code. #tripleee already explained. this is probably what you want -
from subprocess import PIPE
import subprocess
process = subprocess.run(['your_file_name'],shell= "True", bufsize=0,stdin=PIPE,stdout=PIPE, stderr=PIPE, encoding="UTF8")
response=process.stdout

Related

python: multiprocessing.Pipe and redirecting stderr on Windows

I've a main process where I open a multiprocessing.Pipe(False) and send the writing end to a worker Process. Then, in the worker process, I run a Java program using subprocces.Popen(['java', 'myprogram'], stdin=subprocess.PIPE, stdout=subprocess.PIPE). I need to redirect the error of this subprocess to the writing end of multiprocessing.Pipe
For this I referred to this answer by Ilija as this is exactly what I want to achieve, but on my machine(Windows), it throws OSError: [Errno 9] Bad file descriptor
Machine details:
OS - Windows 10 (64bit)
Python version - 3.7.4
Code:
Method 1 (Ilija's answer)
def worker(w_conn):
os.dup2(w_conn.fileno(), 2)
sp = subprocess.Popen(['java', 'myprogram'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
sp.wait()
w_conn.close()
def main():
r_conn, w_conn = multiprocessing.Pipe(False)
process = multiprocessing.Process(target=worker, args=(w_conn,))
process.start()
while not r_conn.poll() and not w_conn.closed:
# Do stuff
else:
# Read error from r_conn, and handle it
r_conn.close()
process.join()
if __name__=='__main__':
main()
Error:
Process Process-1:
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\multiprocessing\process.py", line 297, in _bootstrap
self.run()
File "C:\ProgramData\Anaconda3\lib\multiprocessing\process.py", line 99, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\User\Desktop\Workspace\Error.py", line 14, in worker
os.dup2(w_conn.fileno(), 2)
OSError: [Errno 9] Bad file descriptor
Method 2: In worker function, sending w_conn as argument to Popen
def worker(w_conn):
sp = subprocess.Popen(['java', 'myprogram'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=w_conn)
sp.wait()
w_conn.close()
Error:
Process Process-1:
Traceback (most recent call last):
File "C:\ProgramData\Anaconda3\lib\multiprocessing\process.py", line 297, in _bootstrap
self.run()
File "C:\ProgramData\Anaconda3\lib\multiprocessing\process.py", line 99, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\User\Desktop\Workspace\Error.py", line 13, in worker
sp = subprocess.Popen(['java', 'myprogram'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=w_conn)
File "C:\ProgramData\Anaconda3\lib\subprocess.py", line 728, in __init__
errread, errwrite) = self._get_handles(stdin, stdout, stderr)
File "C:\ProgramData\Anaconda3\lib\subprocess.py", line 1077, in _get_handles
errwrite = msvcrt.get_osfhandle(stderr.fileno())
OSError: [Errno 9] Bad file descriptor
Is there any workaround/alternate method to achive this on Windows?
I still don't know why "Method 1" is not working. Any information regarding this will be appreciated.
"Method 2" is wrong altogether as we can't use Connection object (returned by multiprocessing.Pipe()) as a file handle in subprocess.Popen.
What works is checking for data in stderr of subprocess sp and sending the data through w_conn to main process.
def worker(w_conn):
sp = subprocess.Popen(['java', 'myprogram'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
sp.wait()
if sp.stderr.seek(0, io.SEEK_END)>0:
w_conn.send(sp.stderr.read())
w_conn.close()

Having issue with subprocess library in python during text extraction from image using OCR

I have been using python OCR code to extract text from the image but i am getting some error. I think error is with subprocess library, however it is built in library. So i couldn't figure out the error exactly. can anyone please help me in resolving this error. My code and error are as below.
OCR code
import os
import tempfile
import subprocess
def ocr(path):
temp = tempfile.NamedTemporaryFile(delete=False)
process = subprocess.Popen(['tesseract', path, temp.name], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
process.communicate()
with open(temp.name + '.txt', 'r') as handle:
contents = handle.read()
os.remove(temp.name + '.txt')
os.remove(temp.name)
return contents
str = ocr("C:\\Users\\hp\\Desktop\\MS Thesis\\opencv-text-detection\\opencv-text-detection\\images\\sign.jpg")
print(str)
by executing th above code I got following error
[7]: runfile('C:/Users/hp/Desktop/MS Thesis/python text detection.py', wdir='C:/Users/hp/Desktop/MS Thesis')
Traceback (most recent call last):
File "", line 1, in
runfile('C:/Users/hp/Desktop/MS Thesis/python text detection.py', wdir='C:/Users/hp/Desktop/MS Thesis')
File "C:\Users\hp\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 704, in runfile
execfile(filename, namespace)
File "C:\Users\hp\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 108, in execfile
exec(compile(f.read(), filename, 'exec'), namespace)
File "C:/Users/hp/Desktop/MS Thesis/python text detection.py", line 26, in
str = ocr("C:\Users\hp\Desktop\MS Thesis\opencv-text-detection\opencv-text-detection\images\sign.jpg")
File "C:/Users/hp/Desktop/MS Thesis/python text detection.py", line 15, in ocr
process = subprocess.Popen(['tesseract', path, temp.name], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
File "C:\Users\hp\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 171, in init
super(SubprocessPopen, self).init(*args, **kwargs)
File "C:\Users\hp\Anaconda3\lib\subprocess.py", line 769, in init
restore_signals, start_new_session)
File "C:\Users\hp\Anaconda3\lib\subprocess.py", line 1172, in _execute_child
startupinfo)
FileNotFoundError: [WinError 2] The system cannot find the file specified
I have been using Python 3.7.1 with anaconda on window 7
Look like there is an error because it cannot found the file
if the file is in the same directory I will recommend you use:
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
os.path.join(BASE_DIR, 'file_dir')

Collecting stderr in memory with subprocess.call

I'm trying to collect stderr in memory, instead of directly writing it to a file or stdout. I do this so I can generated the error log file in a certain way. I found a library called StringIO that is an in-memory 'file'. I don't think it does the trick. Here's my code:
buffer = StringIO.StringIO()
status = subprocess.call(args, stdout=log_fps["trace"], stderr=buffer)
if status and self.V_LEVEL:
sys.stderr.write(buffer.getvalue())
print "generated error"
if status:
log_fps["fail"].write("==> Error with files %s and %s\n" % (domain_file, problem_file))
log_fps["fail"].write(buffer.getvalue())
I get the following error:
Traceback (most recent call last):
File "./runit.py", line 284, in <module>
launcher.run_all_cff_domain_examples("ring")
File "./runit.py", line 259, in run_all_cff_domain_examples
result = self.run_clg(in_d["domain"], in_d["problem"], in_d["prefix"])
File "./runit.py", line 123, in run_clg
status = subprocess.call(args, stdout=log_fps["trace"], stderr=buffer)
File "/usr/lib/python2.7/subprocess.py", line 493, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib/python2.7/subprocess.py", line 672, in __init__
errread, errwrite) = self._get_handles(stdin, stdout, stderr)
File "/usr/lib/python2.7/subprocess.py", line 1075, in _get_handles
errwrite = stderr.fileno()
AttributeError: StringIO instance has no attribute 'fileno'
I guess this means that I can't use StringIO to collect stderr in memory. What else can I do, short of writing to a file in /tmp?
stdout = subprocess.check_output(args)
See check_output documentation for more options.
If you don't want to capture stdout, use Popen.communicate:
from subprocess import Popen, PIPE
p = Popen(args, stdout=log_fps["trace"], stderr=PIPE)
_, stderr = p.communicate()
import subprocess
p = subprocess.Popen(args, stdout=log_fps["trace"], stderr=subprocess.PIPE)
_, stderr = p.communicate()
print stderr,

NamedTemporaryFile cannot be acessed from command line

I have the following (simplified) code:
with NamedTemporaryFile() as f:
f.write(zip_data)
f.flush()
subprocess.call("/usr/bin/7z x %s" % f.name)
It dies with the following error:
Traceback (most recent call last):
File "decrypt_resource.py", line 70, in <module>
unpack(sys.argv[2])
File "decrypt_resource.py", line 28, in unpack
print(subprocess.check_output(cmd))
File "/usr/lib/python2.7/subprocess.py", line 568, in check_output
process = Popen(stdout=PIPE, *popenargs, **kwargs)
File "/usr/lib/python2.7/subprocess.py", line 711, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1308, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
However, if I use NamedTemporaryFile(delete=False) and then print & execute the command, it works. What's wrong here?
My System is an ArchLinux with a 3.9.5-1-ARCH kernel.
You are using subprocess.call() incorrectly.
Pass in a list of arguments:
subprocess.call(["/usr/bin/7z", "x", f.name])
The argument is not handled by a shell and is not parsed out like a shell would do. This is a good thing as it prevents a security problem with untrusted command line arguments.
Your other options include using shlex.split() to do the whitespace splitting for you, or, as a last resort, telling subprocess to use a shell for your command with the shell=True flag. See the big warning on the subprocess documentation about enabling the shell.

Python subprocess command arguments

Why if I run subprocess.check_output('ls') everything is working but when I add argument to command like: subprocess.check_output('ls -la') I get error:
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python2.7/subprocess.py", line 537, in check_output
process = Popen(stdout=PIPE, *popenargs, **kwargs)
File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1259, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
How can I pass command arguments into subprocess.check_output()?
You need to split the arguments into a list:
subprocess.check_output(['ls', '-la'])
The subprocess callables do not parse the command out to individual arguments like the shell does. You either need to do this yourself or you need to tell subprocess to use the shell explicitly:
subprocess.check_output('ls -la', shell=True)
The latter is not recommended as it can expose your application to security vulnerabilities. You can use shlex.split() to parse a shell-like command line if needed:
>>> import shlex
>>> shlex.split('ls -la')
['ls', '-la']
You might find sh.py more friendly:
import sh
print sh.ls("-la")

Categories

Resources