在 shell 脚本中检测 python 版本

我想检测一下 Python 是否安装在 Linux 系统上,如果安装了,那么安装的是哪个 python 版本。

我该怎么做呢? 还有什么比解析 "python --version"的输出更优雅的吗?

97758 次浏览
python -c 'import sys; print sys.version_info'

or, human-readable:

python -c 'import sys; print(".".join(map(str, sys.version_info[:3])))'

You could use something along the following lines:

$ python -c 'import sys; print(sys.version_info[:])'
(2, 6, 5, 'final', 0)

The tuple is documented here. You can expand the Python code above to format the version number in a manner that would suit your requirements, or indeed to perform checks on it.

You'll need to check $? in your script to handle the case where python is not found.

P.S. I am using the slightly odd syntax to ensure compatibility with both Python 2.x and 3.x.

using sys.hexversion could be useful if you want to compare version in shell script

ret=`python -c 'import sys; print("%i" % (sys.hexversion<0x03000000))'`
if [ $ret -eq 0 ]; then
echo "we require python version <3"
else
echo "python version is <3"
fi

You can use this command in bash:

PYV=`python -c "import sys;t='{v[0]}.{v[1]}'.format(v=list(sys.version_info[:2]));sys.stdout.write(t)";`
echo $PYV

You can use this too:

pyv="$(python -V 2>&1)"
echo "$pyv"

I used Jahid's answer along with Extract version number from a string to make something written purely in shell. It also only returns a version number, and not the word "Python". If the string is empty, Python is not installed.

version=$(python -V 2>&1 | grep -Po '(?<=Python )(.+)')
if [[ -z "$version" ]]
then
echo "No Python!"
fi

And let's say you want to compare the version number to see if you're using an up to date version of Python, use the following to remove the periods in the version number. Then you can compare versions using integer operators like, "I want Python version greater than 2.7.0 and less than 3.0.0". Reference: ${var//Pattern/Replacement} in http://tldp.org/LDP/abs/html/parameter-substitution.html

parsedVersion=$(echo "${version//./}")
if [[ "$parsedVersion" -lt "300" && "$parsedVersion" -gt "270" ]]
then
echo "Valid version"
else
echo "Invalid version"
fi

You can use the platform module which is part of the standard Python library:

$ python -c 'import platform; print(platform.python_version())'
2.6.9

This module allows you to print only a part of the version string:

$ python -c 'import platform; major, minor, patch = platform.python_version_tuple(); print(major); print(minor); print(patch)'
2
6
9

To check if ANY Python is installed (considering it's on the PATH), it's as simple as:

if which python > /dev/null 2>&1;
then
#Python is installed
else
#Python is not installed
fi

The > /dev/null 2>&1 part is there just to suppress output.

To get the version numbers also:

if which python > /dev/null 2>&1;
then
#Python is installed
python_version=`python --version 2>&1 | awk '{print $2}'`
echo "Python version $python_version is installed."


else
#Python is not installed
echo "No Python executable is found."
fi

Sample output with Python 3.5 installed: "Python version 3.5.0 is installed."

Note 1: The awk '{print $2}' part will not work correctly if Python is not installed, so either use inside the check as in the sample above, or use grep as suggested by Sohrab T. Though grep -P uses Perl regexp syntax and might have some portability problems.

Note 2: python --version or python -V might not work with Python versions prior to 2.5. In this case use python -c ... as suggested in other answers.

Here is another solution using hash to verify if python is installed and sed to extract the first two major numbers of the version and compare if the minimum version is installed

if ! hash python; then
echo "python is not installed"
exit 1
fi


ver=$(python -V 2>&1 | sed 's/.* \([0-9]\).\([0-9]\).*/\1\2/')
if [ "$ver" -lt "27" ]; then
echo "This script requires python 2.7 or greater"
exit 1
fi

Adding to the long list of possible solutions, here's a similar one to the accepted answer - except this has a simple version check built into it:

python -c 'import sys; exit(1) if sys.version_info.major < 3 and sys.version_info.minor < 5 else exit(0)'

this will return 0 if python is installed and at least versions 3.5, and return 1 if:

  • Python is not installed
  • Python IS installed, but its version less than version 3.5

To check the value, simply compare $? (assuming bash), as seen in other questions.

Beware that this does not allow checking different versions for Python2 - as the above one-liner will throw an exception in Py2. However, since Python2 is on its way out the door, this shouldn't be a problem.

If you need to check if version is at least 'some version', then I prefer solution which doesn't make assumptions about number of digits in version parts.

VERSION=$(python -V 2>&1 | cut -d\  -f 2) # python 2 prints version to stderr
VERSION=(${VERSION//./ }) # make an version parts array
if [[ ${VERSION[0]} -lt 3 ]] || [[ ${VERSION[0]} -eq 3 && ${VERSION[1] -lt 5 ]] ; then
echo "Python 3.5+ needed!" 1>&2
return 1
fi

This would work even with numbering like 2.12.32 or 3.12.0, etc. Inspired by this answer.

Detection of python version 2+ or 3+ in a shell script:

# !/bin/bash
ver=$(python -c"import sys; print(sys.version_info.major)")
if [ $ver -eq 2 ]; then
echo "python version 2"
elif [ $ver -eq 3 ]; then
echo "python version 3"
else
echo "Unknown python version: $ver"
fi

In case you need a bash script, that echoes "NoPython" if Python is not installed, and with the Python reference if it is installed, then you can use the following check_python.sh script.

  • To understand how to use it in your app, I've also added my_app.sh.
  • Check that it works by playing with PYTHON_MINIMUM_MAJOR and PYTHON_MINIMUM_MINOR

check_python.sh

#!/bin/bash


# Set minimum required versions
PYTHON_MINIMUM_MAJOR=3
PYTHON_MINIMUM_MINOR=6


# Get python references
PYTHON3_REF=$(which python3 | grep "/python3")
PYTHON_REF=$(which python | grep "/python")


error_msg(){
echo "NoPython"
}


python_ref(){
local my_ref=$1
echo $($my_ref -c 'import platform; major, minor, patch = platform.python_version_tuple(); print(major); print(minor);')
}


# Print success_msg/error_msg according to the provided minimum required versions
check_version(){
local major=$1
local minor=$2
local python_ref=$3
[[ $major -ge $PYTHON_MINIMUM_MAJOR && $minor -ge $PYTHON_MINIMUM_MINOR ]] && echo $python_ref || error_msg
}


# Logic
if [[ ! -z $PYTHON3_REF ]]; then
version=($(python_ref python3))
check_version ${version[0]} ${version[1]} $PYTHON3_REF
elif [[ ! -z $PYTHON_REF ]]; then
# Didn't find python3, let's try python
version=($(python_ref python))
check_version ${version[0]} ${version[1]} $PYTHON_REF
else
# Python is not installed at all
error_msg
fi

my_app.sh

#!/bin/bash
# Add this before your app's code
PYTHON_REF=$(source ./check_python.sh) # change path if necessary
if [[ "$PYTHON_REF" == "NoPython" ]]; then
echo "Python3.6+ is not installed."
exit
fi


# This is your app
# PYTHON_REF is python or python3
$PYTHON_REF -c "print('hello from python 3.6+')";

Yet another way to print Python version in a machine-readable way with major and minor version number only. For example, instead of "3.8.3" it will print "38", and instead of "2.7.18" it will print "27".

python -c "import sys; print(''.join(map(str, sys.version_info[:2])))"

Works for both Python 2 and 3.

The easiest way would be:

if ! python3 --version ; then
echo "python3 is not installed"
exit 1
fi


# In the form major.minor.micro e.g. '3.6.8'
# The second part excludes the 'Python ' prefix
PYTHON_VERSION=`python3 --version | awk '{print $2}'`

This just returns 2.7, 3.6 or 3.9

python -c 'import sys; print(".".join(map(str, sys.version_info[0:2])))'

which is what you usually you need...