にせねこメモ

はてなダイアリーがUTF-8じゃないので移ってきました。

Python 3 で Cygwin 判定

Cygwin から Windows プログラムを呼んだときなど、コマンドライン引数に Cygwin 形式のパス(/cygdrive/~)を与えてもうまく開いてくれなかったりする。
Anaconda PythonCygwin から使ってたりするのだけど、 Cygwin から実行されてるかの判定ができたらいいなあと思ったので調べた。

Python ライブラリで判定できないか?

os.name, sys.platform, platform.system() などが、 OS の判定に使えるらしい。
実際に見てみる。OS は Windows7 64bit である。

Anaconda PythonCygwin から起動した場合:

>>> import sys, os, platform
>>> sys.version
'3.5.1 |Anaconda 2.4.1 (64-bit)| (default, Jan 19 2016, 12:15:43) [MSC v.1900 64 bit (AMD64)]'
>>> os.name
'nt'
>>> sys.platform
'win32'
>>> platform.system()
'Windows'

Cygwin PythonCygwin から起動した場合:

>>> import sys, os, platform
>>> sys.version
'3.4.3 (default, May  5 2015, 17:58:45) \n[GCC 4.9.2]'
>>> os.name
'posix'
>>> sys.platform
'cygwin'
>>> platform.system()
'CYGWIN_NT-6.1'
>>> platform.uname()

Anaconda Pythonコマンドプロンプト(Anaconda Prompt)から起動した場合

>>> import sys, os, platform
>>> sys.version
'3.5.1 |Anaconda 2.4.1 (64-bit)| (default, Jan 19 2016, 12:15:43) [MSC v.1900 64 bit (AMD64)]'
>>> os.name
'nt'
>>> sys.platform
'win32'
>>> platform.system()
'Windows'

比較してみると、 Python のバイナリによって異なっているようで、実行環境による差は見えない。

WindowsPythonCygwin Python を区別するのには使えるが、 Cygwin 上で実行されているかの判別には使えない。

uname コマンド

POSIX 環境であれば uname コマンドが入っている。しかし Windows にはその様なコマンドはない。

Cygwin コンソールで実行すると、

$ uname
CYGWIN_NT-6.1

となる一方、

コマンドプロンプトで実行しようとすると

>uname
'uname' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。

となる。


このコマンドを python から呼んでやって、エラーが起これば少なくとも Cygwin ではないということがわかる。さらに標準出力に CYGWIN が含まれているかどうかを判定すれば、 Cygwin から起動されたかどうかが判定できそうだ。

コード

import subprocess

def checkcygwin():
    try:
        p = subprocess.Popen(
            ['uname'],
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            shell=False
            )
        stdout, stderr = p.communicate()
    except:
        # not posix
        return False
    
    if b'CYGWIN' in stdout: # running in Cygwin
        return True
    else:
        return False

実行結果

CygwinCygwin Python
>>> checkcygwin()
True
Cygwin → Anaconda Python
>>> checkcygwin()
True
コマンドプロンプト → Anaconda Python
>>> checkcygwin()
False

良さそう。


これに更に sys.platform などで分岐を行えば、 Cygwin 上で起動された WindowsPython を判定することもできるはず。