This question already has answers here:
Running shell command and capturing the output
(21 answers)
Closed last year.
I'm building a project for first time and its really confusing. I've included a project through using gitmodules and I'm using Visual Studio and I want to statically link that project in my own project. The issue is that the project doesn't come with a Visual Studio solution, so I'm left with running CMake on this. However, I saw online through looking on GitHub that people use scripts to run all the prerequisite stuff for building. So I've made batch scripts and python scripts and its going well so far.
But I haven't been able to find anywhere online that shows how to get the CMake version using Python.
I want the Python script to detect if CMake is installed or not and if it is installed then to check its version.
Current my Python code looks like this
if cmake --version <= 3.22.1:
exit(1)
This gives me errors though: SyntaxError: invalid syntax
Running cmake --version in the terminal shows the version as expected.
"cmake version 3.22.1"
I'm trying to get the CMake version from the call to be used in an if statement in python rather than just calling cmake --version in python.
Does anyone know how to do this?
Also if this is an XY problem, please let me know. I don't know what I'm doing!
You can check CMake version against 3.22.1 like this:
import subprocess
from packaging import version
def get_cmake_version():
output = subprocess.check_output(['cmake', '--version']).decode('utf-8')
line = output.splitlines()[0]
version = line.split()[2]
return(version)
if version.parse(get_cmake_version()) < version.parse("3.22.1"):
exit(1)
get_cmake_version() runs cmake --version, getting its output with check_output(). Then with a combination of split() and splitlines(), it then gets the third word on the first line and returns it. Then we parse the version number returned by get_cmake_version() with version.parse from the packaging module and compare it to 3.22.1.
Note that the above subprocess.check_output() call throws FileNotFoundError when CMake is not installed. This isn't documented though. The documentation for check_output() says that it can throw CalledProcessError but doesn't mention FileNotFoundError.
You'll probably want to handle these two errors with try/except.
Use Subprocess
subprocess = subprocess.Popen("cmake --version", shell=True, stdout=subprocess.PIPE)
subprocess_return = subprocess.stdout.read()
print(subprocess_return)
You now have the output of the command inside the subprocess_return variable,
Now you can just parse it to get the version number.
import subprocess
import re
try:
msg = subprocess.Popen("cmake --version", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT).stdout.read().decode()
# guess
versions = msg.split()[2]
pat = re.compile(r'[0-9]\.[0-9].+\.[0-9]')
if pat.match(versions):
print(versions.split("."))
else:
print("Invalid!")
except:
print("Invalid!")
Related
So basically, I am using a package online that requires the use of the shell in order to parse data. The line of code that needs to be sent to the shell is as follows:
python scripts/extract.py esm2_t33_650M_UR50D data/output.fasta data/output_esm --repr_layers 33 --include per_tok
Where extract.py contains a Python script that needs to be run.
In order to achieve this, I had to utilize the ! in the code cell in order to send the line of code to the shell.
However, running the code cell returned an invalid syntax error:
File "scripts/extract.py", line 79
print(f"Read {args.fasta_file} with {len(dataset)} sequences")
^
SyntaxError: invalid syntax
Looking online, it seemed this was caused by the f"" functionality not being available in Python 2.x versions. Which is weird since I am currently running Jupyter on Python 3.8.13.
So I checked the version of Python through the shell and realized it was still running on Python 2.7.17
How do I tell the shell explicitly to use Python 3.x interpreter and packages instead of 2.x? I was always under the assumption that the shell would use the same version of Python that Jupyter is running on.
Thank you!
I am on mac OSX.
I have a program where I am trying to call downloaded libraries from the terminal. This is not possible if I don't know where the libraries are. I will use pip as a common library example
>>> os.system("pip -h")
32512
>>> os.system("which pip")
256
I have read this response to the 256 error, however, I still don't understand why it appears here. It says it is "frequently used to indicate an argument parsing failure" however the exact command works because this does not seem to be an argument parsing error to me.
I would like to be able to do something to the effect of:
os.system(os.system("which pip") +" -h")
If there is another way of doing this, I would love to hear it
Don't use os.system like that (and don't use which, either). Try this to find a program:
import os
for bin_dir in os.environ.get("PATH").split(":"):
if 'my_program' in os.listdir(bin_dir):
executable_path = os.path.join(bin_dir, 'my_program')
break
Note that this does assume that PATH was properly set by whatever process started the script. If you are running it from a shell, that shouldn't be an issue.
In general, using os.system to call common *NIX utilities and trying to parse the results is unidiomatic-- it's writing python as if it was a shell script.
Then, instead of using system to run pip, use the solution describe in this answer.
I'm calling another program with a piece of code that looks like this:
import subprocess
lc="/package/bin/program --do stuff"
command_list = lc.split()
ljs=subprocess.Popen(command_list,stdout=subprocess.PIPE)
ljs.communicate()[0]
The string works fine at the UNIX command line and the code works in Python 2.7. But, in Python 3.4, I get an error like this:
File "/package/bin/program", line 2, in <module>
from package import module
ImportError: No module named package
"/package/bin/program" is calling a dependency from another file in the package here, which I think is the core issue. I have calls to other programs that are working fine in 3.4.
What's changed in 3.4 that might be causing this?
(Sorry in advance for the cryptic code - I'm calling company internal tools that I can't expose here).
The problem is that the working directory of the subproccess instance is default the directory of bash shell. To set a new working directory, set the cwd argument in your Popen to your working directory.
Here's an example:
subprocess.Popen(['random' '--command'], stdout = subprocess.PIPE, cwd='C:/Path/To/Working/Directory/')
Comments above have been helpful in exploring the issue, but at the end of the day this seems to be some permissions conflict - adding a sudo -u <user> before the command fixes the issue. Still not clear why Py3 requires this and Py2 doesn't, but perhaps I need to explore the issue more closely with other internal users.
Thanks!
This is probably a windows problem and not a python one, but I'm stumped:
For most applications in my company we are constrained to Python 2.4.2. This isn't a problem for the most part, and my python 2.4.2 installation worked as expected.
The other day one of my colleagues was demonstrating a new utility he had created, which required python 2.5, so we installed python 2.5 and went through his demo.
When he was done I un-installed 2.5 and re-installed 2.4.2. That was when Python stopped parsing command line arguments.
If I run the command line below the supplied argument is not parsed:
C: \TEST >Template_Production_Test.py pt_template.inipt_template.ini
Arguments: ['C:\\ TEST\\ Template_Production_Test.py']
The script scrolls through the contents of argv, and is clearly running as it is returning the script name rather than indicating program not found.
If I run the same script, but this time use the command line below:
C:\\TEST >python Template_Production_Test.py pt_template.inipt_template.ini
Arguments: ['Template_Production_Test.py', 'pt_template.inipt_template.ini']
It all works.
I have no idea what is going on. I uninstalled everything and cleared out the folders, registry and environment variables, then re-installed from scratch. No change in behaviour.
Nobody in the company has seen this before. Anybody out there have any ideas?
Python 2.4.2, running on Win 7.
Seems to be a duplicate. You should search in your registry using regedit.exe for C:\Python24\python.exe %1 and C:\Python25\python.exe %1.
You have to modify the occurrences to C:\Python24\python.exe %1 %*.
With that you will fix two things:
wrong python paths
%* in the end passes the arguments again
Be aware of the right filepaths to python.exe in your specific case.
Good Day all
I am trying to run the following command, but receive various error's I know I have the incorrect syntax or possibly using an incorrect method, would any one be kind enough to point in the correct direction.
Thanks for any assistance
the actual external program path as in windows command line or batch script would be.
"c:\Program Files\SQL Anywhere 11\Bin32\dbbackup.exe" -c "DSN=demo2suite;UID=dba;PWD=sql" -y "D:\Databases\demo2\LIVE\LIVE_BCK"
Python V3.3
my part of the code for this mini(newbie) project would be.
def BackupDatabase():
try:
os.system('c://Program Files//SQL Anywhere 11//Bin32//dbbackup.exe -c "DSN=amos2suite;UID=dba;PWD=sql" -y "D://Databases//AMOS2//LIVE//LIVE_BCK"')
except OSError as e:
WriteLog("error",e)
It's better to use subprocess module.
Something like this:
import subprocess
subprocess.call(['c://Program Files//SQL Anywhere 11//Bin32//dbbackup.exe','-c',
'"DSN=demo2suite;UID=dba;PWD=sql"', '-y','"D://Databases//AMOS2//LIVE//LIVE_BCK"'])