Posted at

ttyとかptsとかについて確認してみる

More than 3 years have passed since last update.

psコマンドのTTY列にttyとかptsはたまた?など表示されますが、良く分かってなかったのでメモ


参考


調べてみる

ttyについてウィキペディアでは以下のように書いてあります。


ttyとは、標準入出力となっている端末デバイス(制御端末、controlling terminal)の名前を表示するUnix系のコマンドである。元来ttyとはteletypewriter(テレタイプライター)のことを指す。


これはttyコマンドの説明ですね。

ttyコマンドをタイプすることで標準入力、標準出力となっている端末デバイスを表示すると。

試しにターミナルからSSHログインしているサーバーでコマンドを実行してみます。

# ターミナルAでログイン

$tty
/dev/pts/0

上記の/dev/pts/0が端末デバイスとなっているようですが、この/dev/pts/0とは何なのでしょうか。

調べてみるとptsはSSHやtelnetで接続している仮想端末(ターミナル)を示すようです。つまり、上記の例ではSSHで接続しているターミナルを標準入力元・標準出力先デバイスとすることでターミナル上に文字の表示をしたり、ターミナルでタイプした入力を受け取るれるようになっているということのようです。

試しに上記SSH接続がされた状態で別のターミナルから同じサーバーにSSHログインしてみます。

# 別のターミナル(ターミナルB)からSSHログイン

$tty
/dev/pts/1

# ログイン中のユーザーを表示
$w
08:55:45 up 28 min, 2 users, load average: 0.00, 0.01, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
ec2-user pts/0 h175-177-004-097 08:30 1.00s 0.02s 0.00s w
ec2-user pts/1 h175-177-004-097 08:52 3:32 0.00s 0.00s -bash

別のターミナルでは同じユーザーでのSSHログインにも関わらず、/dev/pts/1ということで別のファイルがttyに割り当てられていました。別のファイルを割り当てないとターミナルBで標準入力・標準出力を

制御できないからですね。

つまり、現状は以下のような関係となっていることが分かります。


  • ターミナルA->/dev/pts/0

  • ターミナルB->/dev/pts/1


ファイルディスクリプタとの関係

ファイルディスクリプタとは、プログラムがアクセスするファイルや標準入出力などをOSが識別するために用いる識別子です。

以前ファイルディスクリプタについて記事も書きました。

ファイルディスクリプタについて理解する

通常、ファイルディスクリプタは以下のようにそれぞれ割り当てられます。


  • 0->標準入力

  • 1->標準出力

  • 2->標準エラー出力

/proc/[プロセスID]/fd/配下を見ることでプロセスごとのファイルディスクリプタの向き先が分かるので確認してみます。

# ターミナルAで実行

$vim hoge.txt
# Ctrl+Zで停止

# プロセスID確認
$ps
PID TTY TIME CMD
7270 pts/0 00:00:00 bash
7322 pts/0 00:00:00 vim
7330 pts/0 00:00:00 ps

# ファイルディスクリプタ確認
$ ll /proc/7322/fd
合計 0
lrwx------ 1 ec2-user ec2-user 64 4月 28 09:14 0 -> /dev/pts/0
lrwx------ 1 ec2-user ec2-user 64 4月 28 09:14 1 -> /dev/pts/0
lrwx------ 1 ec2-user ec2-user 64 4月 28 09:14 2 -> /dev/pts/0
lrwx------ 1 ec2-user ec2-user 64 4月 28 09:14 4 -> /home/ec2-user/.test.txt.swp

標準入力、標準出力、標準エラー出力のファイルディスクリプタがそれぞれttyコマンドの結果と同じファイルに向いています。

「/dev/pts/0=ターミナルA」だったので上記起動していたVimはターミナルAから標準入力を受け取り、ターミナルAに標準出力・標準エラー出力を表示しているということが分かりました。


遊んでみる

ttyとターミナルの関係が分かり、ttyでは標準出力を受け取れるということなので、/dev/pts/1ファイルを使ってターミナルAからターミナルBにメッセージを送信してみます。

ターミナルAで以下を実行します。

$echo "hoge" > /dev/pts/1

するとターミナルBで標準出力されます。

$hoge

面白いですね。

wコマンドで他のユーザーのttyのファイルを確認し、メッセージの送信ができるということですね。


psでTTYが「?」となっているのは何?

これは結論から言うとデーモンプロセスです。

デーモンプロセスではユーザーに端末から制御されるものでなく、バックグラウンドで動作するプロセスのためttyが割り当たってないよということを意味するものです。

確認のためデーモンプロセスを書きます。


deamon.rb

Process.deamon

sleep

実行し、確認します。

# デーモンプロセス起動

$ruby deamon.rb

# プロセス確認
$ps aux |grep deamon
ec2-user 27831 0.0 0.4 135276 4408 ? Sl 11:38 0:00 ruby deamon.rb
ec2-user 27835 0.0 0.2 110472 2172 pts/1 S+ 11:38 0:00 grep --color=auto deamon

# ファイルディスクリプタ確認
$ll /proc/27831/fd/
合計 0
lrwx------ 1 ec2-user ec2-user 64 4月 28 11:40 0 -> /dev/null
lrwx------ 1 ec2-user ec2-user 64 4月 28 11:40 1 -> /dev/null
lrwx------ 1 ec2-user ec2-user 64 4月 28 11:40 2 -> /dev/null
lr-x------ 1 ec2-user ec2-user 64 4月 28 11:40 3 -> pipe:[36988]
l-wx------ 1 ec2-user ec2-user 64 4月 28 11:40 4 -> pipe:[36988]
lr-x------ 1 ec2-user ec2-user 64 4月 28 11:40 5 -> pipe:[36989]
l-wx------ 1 ec2-user ec2-user 64 4月 28 11:40 6 -> pipe:[36989]

なるほど。

標準入力、標準出力、標準エラー出力が/dev/nullとなってますね。

Webサーバーのhttpdを確認すると以下のようになってました。

$sudo ls -la /proc/27933/fd/

合計 0
dr-x------ 2 root root 0 4月 28 11:46 .
dr-xr-xr-x 9 root root 0 4月 28 11:46 ..
lr-x------ 1 root root 64 4月 28 11:46 0 -> /dev/null
l-wx------ 1 root root 64 4月 28 11:46 1 -> /dev/null
l-wx------ 1 root root 64 4月 28 11:46 2 -> /var/log/httpd/error_log
lrwx------ 1 root root 64 4月 28 11:46 3 -> socket:[37368]
lrwx------ 1 root root 64 4月 28 11:46 4 -> socket:[37369]
lr-x------ 1 root root 64 4月 28 11:46 5 -> pipe:[37384]
l-wx------ 1 root root 64 4月 28 11:46 6 -> pipe:[37384]
l-wx------ 1 root root 64 4月 28 11:46 7 -> /var/log/httpd/access_log

こちらは標準エラー出力はエラーログに書き込むようになってますね。socketのファイルディスクリプタがあるのでリクエストの際やその他プロセスと通信する場合にはこちらを利用するのだと思われます。


mingettyってなんだ?

psコマンドを打つとmingettyというプロセスが確認できます。

$ps aux |grep tty

root 2502 0.0 0.1 6460 1524 ttyS0 Ss+ 08:27 0:00 /sbin/agetty ttyS0 9600 vt100-nav
root 2506 0.0 0.1 4312 1384 tty1 Ss+ 08:27 0:00 /sbin/mingetty /dev/tty1
root 2509 0.0 0.1 4312 1484 tty2 Ss+ 08:27 0:00 /sbin/mingetty /dev/tty2
root 2511 0.0 0.1 4312 1388 tty3 Ss+ 08:27 0:00 /sbin/mingetty /dev/tty3
root 2513 0.0 0.1 4312 1488 tty4 Ss+ 08:27 0:00 /sbin/mingetty /dev/tty4
root 2515 0.0 0.1 4312 1384 tty5 Ss+ 08:27 0:00 /sbin/mingetty /dev/tty5
root 2518 0.0 0.1 4312 1388 tty6 Ss+ 08:27 0:00 /sbin/mingetty /dev/tty6
ec2-user 28120 0.0 0.2 110472 2244 pts/3 S+ 12:55 0:00 grep --color=auto tty

調べてみるとこのmingettyがログインプロンプトを表示することによってユーザーがログインできるようになるもののようです。

ttyだから仮想端末でなく、実際にLinuxマシンにつなぐ際に利用するもののようですね。

以下に書いてあった図が分かり易かったです。

ttyについて ttyやptsってなんぞ?

PC----ssh------/dev/pts/1--sshd----bash #ssh が接続されている

PC----rs232c---/dev/ttyS0--mgetty--bash #rs232c が接続されている