今までそんなシチュエーションにならなかったのが不思議なくらいなのです。Windowsのバッチファイルの中で呼び出すつもりのPythonのスクリプトを書いていて、
標準出力がコンソールに向いているのか、どこかにリダイレクトされているのか知りたい
と思ったのです。この歳になるまでそんな事をついぞ考えないで生きてきたのですから、まずは幸せな人生であった、というべきでしょう。sysモジュールか何かで簡単に知れるんでないかい、と思ったのが間違いでした。
※「トホホな疑問」投稿順Indexはこちら
確かにPythonのsysモジュールには以下のような
-
- sys.stdout
- sys.__stdout__
標準出力を表すファイル・オブジェクトが存在します。特に、後者は「起動時のsys.stdout」を保存することになっていて、sys.stdoutをどこかにリダイレクトしても元に戻せるようになっていたりします。一瞬、リダイレクトされている時に、この二つを比べれば違いあるじゃん、とか思いましたが、
単なる気の迷い
であることに気付きました。だって、Python起動するコマンドラインが書かれているバッチファイルそのものの出力がリダイレクトされているのかも知れないのです、Pythonのスクリプトが走ったときには、全てが終わっています。未練がましく、バッチの出力をリダイレクトしているときと、そうでないときでsys.stdoutの型が変化するかと見てみましたが、勿論、変わりませぬ。
import sys type(sys.stdout) <class '_io.TextIOWrapper'>
まあね、このオブジェクトがラップしている先を掘っていったらいずれは分かるに違いありませんが、そんな気力はありません。大体、バッチレベルでリダイレクトされているのだから、cmd.exe、ウインドウズの機能でそういうことが分からんもんかしら、と調べてみました。ただ、「リダイレクト」などで調べると標準ストリームのリダイレクトよりも、URLのリダイレクトなどネットねたがヒットしてきます。これはいけないと思って、stdout とか標準ストリームもキーワードに加えていると、ヒットしてくるのは、「どうやってリダイレクトするか」、ぶっちゃけ
> とか 2>&1 とか
の世界、そうされている内側にいて、外がどうなっているのか知りたいんだよ、私は。ようやく見つけました。総武ソフトウエア推進所様の以下の記事であります。
まさに、私が知りたかったことズバリ。そこに記されている情報によれば、
.NET Framework 4.5 以降で使えるIsOutputRedirectedプロパティ
使えば分かるのでした。Windows上のPythonで調べていても埒が明かない感じだったので、ここはありがたく上記で逃げよう。上記の記事は、VBだったのですが、私は、C#派なので、バッチ内で使えるような小さなコマンドラインプログラムを書いてみました。こんな感じ。
こいつを使えば、バッチファイルの標準出力がどこ向いているか分かる筈。テスト用のバッチファイル hogehoge.bat がこちら、
@echo off isStdoutRedirected if ERRORLEVEL 1 ( SET IS_REDIRECT=YES ) ELSE ( SET IS_REDIRECT=NO ) python foo.py
そして肝心の「行先を知りたい」と思っているPythonスクリプトのテスト用ファイル foo.py がこちら。
import os if "IS_REDIRECT" in os.environ: print("IS_REDIRECT = {0}".format(os.environ["IS_REDIRECT"])) else: print(os.environ)
リダイレクトしないときと、した時で反応を見てみましょう。
$ hogehoge CONSOLE. IS_REDIRECT = NO $ hogehoge >a.txt $ type a.txt REDIRECTED. IS_REDIRECT = YES
まあね、目的は達しましたが、釈然としないです。Python書いていた筈が、いつの間にかC#になっている。なんとかならないものかなあ、トホホ。