This question already has answers here:
Detect python version in shell script
(18 answers)
Closed 4 years ago.
I was trying to write a bash script to test the python version. However, I found python --version behave weirdly for python 2, as I can't process its output using any tool. I have tested the same script on Mac OS (10.13.5) and AWS Linux (GUN/Linux #1 SMP Fri Feb 16 00:18:48 UTC 2018). So I think the problem is related to python 2.
The script and corresponding output are:
$ echo $(python --version) | awk '{print $2}'
> Python 2.7.10
But the output should be 2.7.10.
$ echo $(python --version) > weird.txt
> Python 2.7.10
$ cat weird.txt
>
So the output cannot be written into a file as well.
The same script to test for python3 has a totally different result
$ echo $(python3 --version) | awk '{print $2}'
> 3.6.5
But python3's output can be written into a file.
$ echo $(python3 --version) > weird.txt
$ cat weird.txt
> Python 3.6.5
I have found the reason for this difference is that python --version does not output a normal string or whatsoever. Maybe it calls another command to output the result for it??? Thus the result cannot be caught by current process?? (just pure guess here)
Can anyone help me to figure out why there is the difference here? There are probably of million ways to test for python version. But I'm just super curious about what is happening here.
Thanks for all the replies. Just found a useful answer explaining that why python -V outputs to stderr:
Why does python print version info to stderr?
Python outputs the version to standard error (stderr) up to version 3.3 according to issue 18338 and as noted here, so redirect accordingly:
$ echo $(python --version 2>&1) | awk '{print $2}'
2.7.14
The command substitution is unnecessary and this could be written as:
$ python --version 2>&1 | awk '{print $2}'
How about using Python command itself using platform library of it(which is a very common in use).
python -c 'import platform; print(platform.python_version())'
When I run it I get Python's exact version.
Related
Anyone can explain me why this
python -V | awk '{print $2}'
returns this
Python 2.7.5
instead of
2.7.5
What to do to return only the version number without "Python " ?
If you run
python -V >/dev/null
you will notice that you still get output! Apparently, python -V prints its output to stderr, not to stdout.
In a bourne-like shell, this should work:
python -V 2>&1 | awk '{print $2}'
How about using pure python command itself(I need to format it with dots in between though)
python -c 'import sys; print sys.version_info[0],sys.version_info[1],sys.version_info[2]'
OR as per Chris's comment use:
python -c 'import sys; print(".".join(map(str, sys.version_info[:3])))'
This looks like a Python issue because using python print or call subprocess with cmd echo, I can get different results.(See examples in below)
The question is how to properly print wide chars in cmd.exe under chcp65001?
Is there an option in python print method or any special methods I need to do to adapt the Windows environment.
OS Win7 64bit.
==GOOD==
C:\>python -c "import subprocess; subprocess.run('cmd.exe /c echo 啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊', shell=True)"
啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
==BAD==
C:\> python -c "print('啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊')"
啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊
�啊啊啊啊啊啊啊啊啊啊啊
��啊啊啊啊啊啊
�啊啊啊
�啊
C:\>chcp
Active code page: 65001
C:\>python -V
Python 3.5.2
There is already a Perl base fix:
C:\>python -c "print('啊啊啊啊啊啊啊啊啊啊啊啊啊')" | perl -Mutf8 -ne "BEGIN{binmode(STDIN,':unix:encoding(utf8):crlf');binmode(STDOUT, ':unix:encoding(utf8):crlf');}print"
啊啊啊啊啊啊啊啊啊啊啊啊啊
C:\>chcp
Active code page: 65001
Why am I getting the last octet repeated when my Perl program outputs a UTF-8 encoded string in cmd.exe?
It would be good to have the Python Solution
I am doing two "similar" things:
(1) in python
import os
os.system('cat ...input | awk -f ...awk' -v seed=$RANDOM)
(2) in linux terminal
cat ...input | awk -f ...awk' -v seed=$RANDOM
Actually, my awk file will return a randomized input file, but if I run way(1) many times, the result always be same(only one result). But If I run way(2), then every time I can get a randomized file. What's wrong with it?
If I want to run this command in python, how should I do then?
Thank you so much for you answer.
EDIT:
Adding the actual code:
(1) in python
import os
os.system("cat data/MD-00001-00000100.input | awk -f utils/add_random_real_weights.awk -v seed=$RANDOM")
(2) in linux:
cat data/MD-00001-00000100.input | awk -f utils/add_random_real_weights.awk -v seed=$RANDOM
I found it here: https://netsec.ws/?p=337
echo os.system('/bin/bash')
os.system is from python but echo is not, I think... what language is this exactly?
If you looked at the echo tag, you'll see its description: "Simple function outputting text. Exists in script languages.", if you're running Linux or Mac and even Windows Command Prompt you can enter this:
$ echo Hello shell world
Output:
Hello shell world
echo is useful for testing shell glob expansion, echoing the values of environment variables and sending output to stdins of other programs, for example try this with Bash:
$ echo 'print("Spam" * 2)' | python -
Output:
SpamSpam
And this:
$ echo 'import os; os.system("echo SPAM")' | python -
Output:
SPAM
This command does not work as expected:
$ python -V >> logfile.txt
The python version is displayed on screen, but does not end up in the logfile, what is needed to get it into the logfile?
$ python -V 2>> logfile.txt
python -V writes to stderr instead of stdout that's why you must append your append operator with 2.
the -V output is going to stderr, so you need to redirect it like this:
python -V 2>> logfile.txt