Linux における標準入力(stdin)の仕組みと Python の input()
はじめに
Linux の標準入力(stdin)はどこに存在し、どのように動作しているのでしょうか?
本記事では、Linux における標準入力の実体、stdin の動作、そして Python の input() がどのように標準入力を扱うのかについて詳しく解説します。
1. 標準入力(stdin)はどこにあるのか?
/dev/stdin
stdin へのシンボリックリンク
ls -l /dev/stdin で確認可能
/proc/self/fd/0
stdin を指すファイルディスクリプタ
ls -l /proc/self/fd/0 で確認可能
2. /proc/self/fd/0 に外部からの標準入力データが入るのか?
/proc/self/fd/0 は 現在のプロセスがどこから標準入力を受け取っているかを指し示す だけであり、データが直接保存されるわけではありません。
/proc/self/fd/0 は 現在のプロセスがどこから標準入力を受け取っているかを指し示す だけであり、データが直接保存されるわけではありません。
標準入力の種類と /proc/self/fd/0 の変化
(1) キーボードからの入力
cat /proc/self/fd/0
この状態でキーボードから入力すると、入力した内容がそのまま出力されます。
(2) ファイルを標準入力として渡す
echo "Hello, World!" > input.txt
cat < input.txt
ls -l /proc/self/fd/0 # → input.txt を指す
結果:
/proc/self/fd/0 -> /path/to/input.txt
→ stdin は input.txt を指す
(3) パイプを使う
echo "Hello via Pipe" | cat
ls -l /proc/self/fd/0 # → パイプを指す
結果:
/proc/self/fd/0 -> pipe:[12345]
→ stdin はパイプの出力を指す
結論:
- /proc/self/fd/0 はデータが保存されるわけではない
- stdin の入力元(キーボード、ファイル、パイプ)によって動的に変化する
3. Python の input() メソッドはどこを参照するのか?
input() の参照先を確認する方法
以下の Python コードを実行すると、input() がどこを参照しているか確認できます。
import os
import sys
print(f"sys.stdin: {sys.stdin}")
print(f"/proc/self/fd/0 -> {os.readlink('/proc/self/fd/0')}")
通常入力時
sys.stdin: <_io.TextIOWrapper name='<stdin>' mode='r' encoding='utf-8'>
/proc/self/fd/0 -> /dev/pts/0 # ターミナル
sys.stdin の内容
sys.stdin は、Python の標準入力ストリームを表します。
- <_io.TextIOWrapper ...> は Python の sys.stdin が テキスト入力を扱うファイルのようなオブジェクト であることを示しています。
- name='<stdin>' は、このオブジェクトが標準入力 (stdin) に関連付けられていることを意味します。
- mode='r' は、このストリームが「読み取り専用(read)」であることを示します。
- encoding='utf-8' は、この入力が UTF-8 でエンコードされていることを意味します。
このことから、Python の input() は sys.stdin を通じて標準入力を読み取る ということがわかります。
/proc/self/fd/0 の内容
/proc/self/fd/0 -> /dev/pts/0
- /proc/self/fd/0 は、現在のプロセスの 標準入力 (stdin) を指すファイルディスクリプタ。
- -> /dev/pts/0 は、stdin が 仮想端末 /dev/pts/0(ターミナル)を参照している ことを示しています。
/dev/pts/0 とは?
- pts/0 は、Linux の 仮想端末(pseudo terminal slave, pts)の 1 つ です。
- tty コマンドで現在のターミナルを確認できます:
$ tty
/dev/pts/0
Discussion