keep-loving-pythonのブログ

Pythonを愛し続けたいです(Pythonが流行っている限りですが。。。)

⭐重要。解決。stdoutが何かにリダイレクトされているか、調べる方法。pythonスクリプトで。

背景

pythonpythonとして動かすときはいいけれど、
開発環境の中で、それを構成するツールというか、言語として利用される場合、
pythonコード内のログやprintの出力先が、よくわからない場合がある。

解決策

ChatGPTに教えてもらった

Q

stdoutが何かにリダイレクトされているか、調べる方法。pythonスクリプトで。

A

Python スクリプト内で、stdout(標準出力)がターミナル(コンソール)ではなく、ファイルやパイプにリダイレクトされているかどうかを調べる方法はいくつかあります。

以下に、最もよく使われる方法を紹介します。


✅ 方法:sys.stdout.isatty() を使う

import sys

if sys.stdout.isatty():
    print("stdout はターミナル(tty)に接続されています。")
else:
    print("stdout はファイルやパイプなどにリダイレクトされています。")

🔍 解説:

  • isatty() は「これはターミナルか?」という意味で、

    • True → ターミナルに出力されている(リダイレクトされていない)
    • False → ファイルやパイプなどにリダイレクトされている

🔧 補足:出力先のファイル名やデバイス名を確認したい場合

sys.stdout.fileno()os.ttyname() を組み合わせることで、出力先がどこなのかも調べられます(リダイレクトされていないときのみ有効)。

import sys
import os

try:
    ttyname = os.ttyname(sys.stdout.fileno())
    print(f"stdout は {ttyname} に出力されています。")
except OSError:
    print("stdout はファイルまたはパイプにリダイレクトされています。")

💡 応用:printとログの両方に出力するには?

リダイレクトされていると分かったら、print() の代わりに、ログとターミナル両方に出したいなら以下のようにします:

import sys
import logging

logging.basicConfig(level=logging.INFO)

def log_and_print(message):
    logging.info(message)
    print(message, file=sys.__stdout__)  # 元のstdoutを使って出力

log_and_print("これは両方に出力されます。")

必要に応じて、より詳細な出力先チェックも紹介できます。

コメント

以下がよかった。
ビックリした。

import sys

if sys.stdout.isatty():
    print("stdout はターミナル(tty)に接続されています。")
else:
    print("stdout はファイルやパイプなどにリダイレクトされています。")