0

With the python --version as input in the terminal, I'd like to confirm (also in the shell in the form of shell programming) whether any python versions installed are 3 or higher. For example,

Python 3.2.1

Would yield True or some form of confirmation, where as python2.2p1 or Python 2.1.4 would yield False.

I've tried using regex through sed or grep, but can't get it.

Note, this is a different matter from what some think to be a duplicate of, as I'm asking the shell programming code that can automate confirmation of python3 or higher being installed, not a way to manually check it (just entering python --version).

7
  • 1
    See stackoverflow.com/questions/8917885/… Commented May 24, 2019 at 13:57
  • 3
    Isn't that the output when Python is not installed? Commented May 24, 2019 at 13:58
  • In your case it seems like python is not installed at all. To capture this case you should ask your package manager instead of using python -V. Which package manager do you use? is it apt? Also, if you want to use version 3 then call python3 instead of just python. Commented May 24, 2019 at 13:58
  • This output is from the Ubuntu command-not-found hook for Bash. It should not even run from within a script, to my understanding. Commented May 24, 2019 at 14:24
  • 2
    This is not a dupe, at least not of the chosen dupe target. The question here is not how to get Python to report its version (the subject of the dupe target and all its answers), but rather how to write a shell script that interprets that (and perhaps other) output. Commented May 24, 2019 at 16:24

3 Answers 3

3

With the python --version as input in the terminal, I'd like to confirm (also in the shell in the form of shell programming) whether any python versions installed are 3 or higher.

If the python command launches any version of cpython, then the output of python --version (to its stderr, not stdout) will have the form:

Python X.Y.Z

You can test that in a shell script like so:

if python --version 2>&1 | grep -q '^Python 3\.'; then
  # It's python 3 ...
else
  # It's not python 3; maybe not installed
fi

Note that the output you originally presented in the question indicated that Python was not installed at all. The above approach will execute the else branch in that event. Note also that it is possible for Python to be installed with a different name -- for example, on the system where I am typing this, python is Python 2.7.5, but Python 3.4.8 is available via the command python3. You could extend the above to test some possible alternative names for Python 3, but you cannot safely, reliably, or efficiently perform an exhaustive test for whether Python 3 is installed at all, under any name or path.

Sign up to request clarification or add additional context in comments.

1 Comment

On reconsidering, I think this should be the made the accepted answer, and my solution is over engineered considering the requirement.
1

The easiest way to do this in Bash is using sort -V.

To solve the problem of comparing version strings in general in bash, here is an simple compare() function that accepts two arguments a and b and returns true if a <= b. And then some unit tests showing its validity for various Python version inputs:

# test.sh

compare() {
  local a=$1 ; local b=$2
  [ "$( (echo "$a" ; echo "$b") | sort -V | head -1)" == "$a" ]
}

test22p1() {
  compare "2.2p1" "3.0.0"
  assertTrue "$?"
}

test214() {
  compare "2.1.4" "3.0.0"
  assertTrue "$?"
}

test300() {
  compare "3.0.0" "3.0.0"
  assertTrue "$?"
}

test372() {
  compare "3.7.2" "3.0.0"
  assertFalse "$?"
}

. shunit2

Output:

▶ bash test.sh
test22p1
test214
test300
test372

Ran 4 tests.

OK

(Those unit tests assume that shunit2 is installed of course.)

About the function:

It just echoes $a then $b on two separate lines, pipes into sort -V, and takes the head. If the head is equal to the left-hand side, true is returned ; otherwise if it is equal to the right-hand side, false is returned.

In your question you mentioned you really want to know if Python 3 or greater is installed, so you could modify it and have something like this instead:

python3_installed() {
  local a b
  a=$(python --version 2>&1 | perl -pe 's/python *//i') ; b=3
  [ "$( (echo "$a" ; echo "$b") | sort -V | head -1)" == "$b" ]
}

This function will compute the actual version of Python installed, and compare it to "3" using sort -V and return false unless 3 or greater is installed.

Note use of Perl there to do a case-insensitive regex search and replace. (Not all sed's have the case-insensitive ability.)

The great thing about doing it this way is you can then have readable code when you call it, like:

if python3_installed ; then
  # yes it is!
else
  # ...
fi

Finally, according to the docs for sort -V (from the BSD manual; POSIX doesn't specify a -V option, but most sorts seem to have it):

`-V, --version-sort`

Sort version numbers. The input lines are treated as file names in form PREFIX VERSION SUFFIX, where SUFFIX matches the regular expression (.([A-Za-z~][A-Za-z0-9~]*)?)*. The files are compared by their prefixes and versions (leading zeros are ignored in version numbers, see example below). If an input string does not match the pattern, then it is compared using the byte compare function. All string comparisons are performed in C locale, the locale environment setting is ignored.

Comments

-2

Here is sample awk script to do the job:

echo $(python --version) | awk 'BEGIN{found="false"}/python-3/{found="true"}END{print found}'

4 Comments

That's a useless use of echo. And it does nothing to reveal which version you have.
echo is used to provide standard-out to awk. Without the echo command, awk requires input file.
No, you are completely mistaken. If Python prints the version information to standard output, the pipe feeds that to Awk's standard input just as well as from echo; and if it doesn't, your echo doesn't help at all.
... and it doesn't. python --version directs its output to stderr, not stdout. Moreover, its error output when python is a version-3 cpython does not match /python3/.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.