How to invoke C executable file using Python - python

I have a compiled binary for Linked list written in c. I placed the executable in /usr/bin/ as /usr/bin/app where app is the name of the executable. This was compiled using gcc.
Can anyone help me to invoke this (app) using a python script.
I have written a script below to do this but seems to give errors. I am very new to python and have very basic knowledge on this. I am just exploring pythons features.
Below is the script code:
#!/usr/bin/env python
import subprocess
proc = subprocess.Popen(['\usr\bin\app'],
stdin = subprocess.PIPE,
stdout = subprocess.PIPE,
stderr = subprocess.PIPE
)
(out, err) = proc.communicate()
print out
Here are the errors:
Traceback (most recent call last):
File "./LinkedList.py", line 7, in <module>
stderr = subprocess.PIPE
File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1249, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
Thank you for your assistancce

Per Comments the answer was:
Use forward slashes '/usr/bin/app'
Personally though I would strongly consider using os.path.join or str.join and os.sep so you don't have to remember which way the slashes should go.
http://docs.python.org/2/library/os.html
http://docs.python.org/2/library/os.path.html

Related

How to run bash commands using subprocess.run on windows [duplicate]

This question already has answers here:
Python subprocess.run('ls',shell=True) not working on windows
(2 answers)
Closed 1 year ago.
I want to run shell scripts and git-bash commands using subprocess.run(), in python 3.7.4. When I run the simple example on the subprocess documentation page this happens:
import subprocess
subprocess.run(["ls", "-l"])
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "C:\pycharm\project\envs\lib\subprocess.py", line 472, in run
with Popen(*popenargs, **kwargs) as process:
File "C:\pycharm\project\envs\lib\subprocess.py", line 775, in __init__
restore_signals, start_new_session)
File "C:\pycharm\project\envs\lib\subprocess.py", line 1178, in _execute_child
startupinfo)
FileNotFoundError: [WinError 2] The system cannot find the file specified
# it also fails with shell=True
subprocess.call(["ls", "-l"], shell=True)
'ls' is not recognized as an internal or external command,
operable program or batch file.
1
The message from shell=True is a message from windows cmd, which suggests subprocess is not sending commands to git-bash.
I am using a conda environment located in the project/envs/ folder for python. I have also installed git-bash.
I also tried setting the env and got the same error.
import os
import subprocess
my_env = os.environ.copy()
my_env["PATH"] = 'C:\Program Files\Git\;' + my_env["PATH"]
subprocess.run(['git-bash.exe', 'ls', '-l'], env=my_env)
Traceback (most recent call last):
File "<input>", line 3, in <module>
File "C:\pycharm\project\envs\lib\subprocess.py", line 472, in run
with Popen(*popenargs, **kwargs) as process:
File "C:\pycharm\project\envs\lib\subprocess.py", line 775, in __init__
restore_signals, start_new_session)
File "C:n\pycharm\project\envs\lib\subprocess.py", line 1178, in _execute_child
startupinfo)
FileNotFoundError: [WinError 2] The system cannot find the file specified
I can get it to run by pointing at the git-bash.exe, but it returns an empty string instead of the files in my directory
import subprocess
subprocess.run(['C:\Program Files\Git\git-bash.exe', 'ls', '-l'], capture_output=True)
CompletedProcess(args=['C:\\Program Files\\Git\\git-bash.exe', 'ls', '-l'], returncode=0, stdout=b'', stderr=b'')
I would appreciate any advice on the best way to get this working as shown on the subprocess documentation page.
I found that I can run commands using ...Git\bin\bash.exe instead of the ...\Git\git-bash.exe, like this:
import subprocess
subprocess.run(['C:\Program Files\Git\\bin\\bash.exe', '-c','ls'], stdout=subprocess.PIPE)
CompletedProcess(args=['C:\\Program Files\\Git\\bin\\bash.exe', '-c', 'ls'], returncode=0, stdout=b'README.md\n__pycache__\nconda_create.sh\nenvs\nmain.py\ntest.sh\nzipped\n')
Try this
p = subprocess.Popen(("ls", "-l"), stdout=subprocess.PIPE)
nodes = subprocess.check_output(("grep"), stdin=p.stdout)
p.wait()
ls is Linux shell command for listing files and directories
dir is Windows command line command for listing files and directories
Try to run dir in Windows command line. If it works, try to run the same command using python subprocess:
import subprocess
subprocess.run(["dir"])
For a machine with Windows Operating System, Try the following
import subprocess
subprocess.run(["dir", "/p"], shell=True)
"ls" is replaced with "dir", "-l" is replaced with "/l" and the "shell" is set to true
For a machine with Linux/Mac Operating System, Try the following
import subprocess
subprocess.run(["ls", "-l"])

python: stderr with shell=True or shell=False in subprocess module

I have been testing the stderr with the subprocess module. If I write a simple test with shell=True with the linux shell command ls intentionally bad typed:
p=subprocess.Popen(["lr"],stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=True)
out, err=p.communicate()
print ("standard error")
print(err)
it outputs the usual from the shell: lr: command not found.
But if shell=False, I don't quite understand why the program has an error executing
Traceback (most recent call last):
File "importInteresantes.py", line 6, in <module>
p=subprocess.Popen(["lr"],stdout=subprocess.PIPE,stderr=subprocess.PIPE,shell=False)
File "/usr/lib/python2.7/subprocess.py", line 390, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1024, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
I thought that it would give me the same output. Is the code wrong or is the point of view that I should obtain the same stderr?
NOTE: Just in case I also tried with python3
With shell=True, Python launches a shell and tells the shell to run lr. The shell runs just fine, fails to find an lr program, and produces error output reporting this failure.
With shell=False, Python tries to run lr directly. Since there is no lr program to run, Python can't find an executable file corresponding to lr. Python can't launch the subprocess at all, and there are no stdout or stderr streams to read from. Python raises an exception reporting its failure to find the file.
This behavior is normal and expected.

subprocess.call says there's no such file or directory, but os.path.isfile says there is

I have an executable file that I'd like to run from Python. I define a path variable pointing at it:
>>> path = '/root/Cognos/Cognos/linuxi38664h/issetupnx'
I verify that I am in fact pointing at a file and not a directory:
>>> from os.path import isdir, isfile
>>> isdir(path)
False
>>> isfile(path)
True
But as soon as I try to run the executable file via subprocess.call...
>>> from subprocess import call
>>> call([path])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.7/subprocess.py", line 524, in call
return Popen(*popenargs, **kwargs).wait()
File "/usr/lib64/python2.7/subprocess.py", line 711, in __init__
errread, errwrite)
File "/usr/lib64/python2.7/subprocess.py", line 1308, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
It tells me the file doesn't exist now.
The only possibility I can think of is that maybe the executable itself is being found and run fine, but the executable is failing saying that something it needs (what?) isn't found. I'm not sure how I would test this theory, though... or even if it's possible.
Another possibility might be some kind of permissions issue? Although I can't think of why I would have proper permissions to see the file but then I suddenly wouldn't be able to see it the moment I try running it.
Instead of using call, I should have used check_output. Then the error would have included all of the messages printed to stdout and stderr.
path = '/root/Cognos/Cognos/linuxi38664h/issetupnx'
from subprocess import check_output
check_output([path])
Then I would have gotten a more detailed message about how it failed to load shared libraries.
execute this code as root:
import subprocess as sp
path = '/root/Cognos/Cognos/linuxi38664h/issetupnx'
proc = sp.Popen([path],stdin=sp.PIPE)
proc.communicate()

The system cannot find the file specified when calling copy from python

Here's my copy.py:
from subprocess import call
call("copy p2.txt p3.txt")
If in command prompt I use
copy p2.txt p3.txt it copies fine.
but when I use python copy.py it gives me:
Traceback (most recent call last):
File "copy.py", line 2, in <module>
call("copy p2.txt p3.txt")
File "C:\Python27\lib\subprocess.py", line 493, in call
return Popen(*popenargs, **kwargs).wait()
File "C:\Python27\lib\subprocess.py", line 679, in __init__
errread, errwrite)
File "C:\Python27\lib\subprocess.py", line 896, in _execute_child
startupinfo)
WindowsError: [Error 2] The system cannot find the file specified
If I replace the python call to copy with xcopy, it works fine.
Why would this be?
When subprocess.call()ing a command like in a shell, you'll need to specify shell=True as well.
from subprocess import call
call("copy p2.txt p3.txt", shell=True)
The reason you need to use shell=True in this case is that the copy command in Windows is not actually an executable but a built-in command of the shell (if memory serves right). xcopy on the other hand is a real executable (in %WINDIR%\System32, which is usually in the %PATH%), so it can be called outside of a cmd.exe shell.
In this particular instance, shutil.copy or shutil.copy2 might be viable alternatives.
Please note that using shell=True can lead to security hazards, or as the docs put it:
Warning: Using shell=True can be a security hazard. See the warning under Frequently Used Arguments for details.

Opening a network file in Cytoscape using cmd and Python

So I have a python script that produces a networkx graph and exports it as .graphml and I want script to also be able to open cytoscape with the network loaded without any work on the users part. I understand:
cytoscape.bat -N C:\Somepath\with\a\networkx.graphml
and it works fine when I use it. As does:
cd "C:\Program Files\Cytoscape_v3.0.0"
cytoscape.bat
However, I can't seem to get either os.system or subprocess to run properly, my current configuration is:
p = subprocess.Popen("cytoscape.bat", cwd="C:/Program Files/Cytoscape_v3.0.0")
stdout, stderr = p.communicate()
But the throws a file-not-found-exception.
I've been reading up on other stackoverflow posts and python docs on running .bats and doing cmd operations, and can get the basics to work. However, this seems somewhat more complicated, and I'm not sure where I'm going wrong!
As requested I exceptions:
The file not found and incorrect path exceptions:
Traceback (most recent call last):
File "CytoScapeExporter.py", line 219, in <module>
p = subprocess.Popen("cytoscape.bat", cwd="\"C:/Program Files/Cytoscape_v3.0
.0\"")
File "C:\Python27\lib\subprocess.py", line 679, in __init__
errread, errwrite)
File "C:\Python27\lib\subprocess.py", line 896, in _execute_child
startupinfo)
WindowsError: [Error 267] The directory name is invalid
Traceback (most recent call last):
File "CytoScapeExporter.py", line 219, in <module>
p = subprocess.Popen("cytoscape.bat", cwd="C:/Program Files/Cytoscape_v3.0.0
")
File "C:\Python27\lib\subprocess.py", line 679, in __init__
errread, errwrite)
File "C:\Python27\lib\subprocess.py", line 896, in _execute_child
startupinfo)
WindowsError: [Error 2] The system cannot find the file specified
A slightly different JVM error, it is produced by this code:
os.system("\"C:/Program Files/Cytoscape_v3.0.0/cytoscape.bat\"")
Error: missing `server' JVM at `C:\Program Files (x86)\Java\jre7\bin\server\jvm.
dll'.
Please install or use the JRE or JDK that contains these missing components.
C:\Program Files\Cytoscape_v3.0.0
From the documentation:
"If cwd is not None, the child’s current directory will be changed to cwd before it is executed. Note that this directory is not considered when searching the executable, so you can’t specify the program’s path relative to cwd."
You have to pass the full path of the command to subprocess.Popen.

Categories