POSIX仕様は、制御端末が関係する場合の賭けを実際にヘッジし、それによって定義します。
- 端末の制御
- 端末を参照している可能性のあるいくつかの特別なファイルのどれが意図されているかという問題は、POSIX.1では扱われていません。パス名
/dev/tty
は、プロセスに関連付けられた制御端末の同義語です。
それは定義リストにあります-それがすべてです。しかし、一般的な端末インターフェイスでは、さらにいくつかが言われています:
端末は、その制御端末としてプロセスに属する場合があります。制御端末を持つセッションの各プロセスには、同じ制御端末があります。端末は最大で1つのセッションの制御端末である場合があります。セッションの制御端末は、実装で定義された方法でセッションリーダーによって割り当てられます。セッションリーダーに制御端末がなく、O_NOCTTYオプションを使用せずにセッションに関連付けられていない端末デバイスファイルを開く場合(open()を参照)、端末がセッションの制御端末になるかどうかは実装定義です盟主。
制御端末は、fork()関数呼び出し中に子プロセスによって継承されます。プロセスは、プロセスとの新しいセッションを作成するときに、制御端末を放棄します。setsid()
関数; 制御端末としてこの端末を持っていた、古いセッションに残っている他のプロセスは、引き続きそれを持っています。制御端末に関連付けられているシステム内の最後のファイル記述子(現在のセッションにあるかどうかに関係なく)を閉じると、その端末を制御端末として使用していたすべてのプロセスが制御端末を使用しなくなるかどうかは不明です。この方法で制御端末が放棄された後、セッションリーダーが制御端末を再取得できるかどうか、およびその方法は指定されていません。他のプロセスが制御端末を開いたままにしている場合、プロセスは、制御端末に関連付けられているファイル記述子をすべて閉じるだけでは、制御端末を放棄しません。
不特定の部分がたくさん残っています-正直なところ、それは理にかなっていると思います。端末は重要なユーザーインターフェイスですが、実際のハードウェアやプリンターのような場合もありますが、多くの場合xterm
、エミュレーターのようなものはほとんどありません。。端末を具体的に説明するのは困難です-とにかく、Unixよりも端末の機能が多いため、Unixの利益に大きく影響するとは思いません。
とにかく、POSIXはps
、cttyが関係している場所でどのように動作すべきかについてもかなり不信感を持っています。
-a
スイッチがあります:
- 端末に関連するすべてのプロセスの情報を書き込みます。実装では、このリストからセッションリーダーを省略できます。
すごい。セッションリーダーは省略できます。それはあまり役に立ちません。
そして-t
:
- termlistで指定された端末に関連するプロセスの情報を書き込みます。アプリケーションは、termlistが
<blank>
コンマ区切りのリスト形式の単一の引数であることを確認する必要があります。端末識別子は、実装で定義された形式で指定されます。
...これは別の失望です。しかし、XSIシステムについて次のように言っています。
- XSI準拠のシステムでは、彼らは、次の2つの形式のいずれかで与えられなければならない:デバイスのファイル名(例えば、
tty04
デバイスのファイル名が始まる場合)、またはtty
単に識別子、文字を以下tty
(例えば、04
)。
それは少し良いですが、道ではありません。XSIシステムにも-d
スイッチがあります。
- セッションリーダーを除くすべてのプロセスの情報を記述します。
...それは少なくとも明確です。-o
utputスイッチもtty
フォーマット文字列で指定できますが、すでに述べたように、その出力フォーマットは実装定義です。それでも、私はそれが得られるのと同じくらい良いと思います。私は-多くの作業で-上記のスイッチをいくつかの他のユーティリティと組み合わせて使用すると、かなり良い球場が得られると思います。しかし、正直に言うと、いつ、どのように動作するかわかりません。また、そのような状況を想像することもできませんでした。しかし、追加fuser
しfind
てパスを確認できれば、と思います。
exec 2<>/dev/null
ctty=$(sh -c 'ps -p "$$" -o tty=' <&2)
sid=$(sh -c 'ps -Ao pid= -o tty=|
grep '"$ctty$"' |
grep -Fv "$(ps -do pid=)"' <&2)
find / -type c -name "*${ctty##*/}*" \
-exec fuser -uv {} \; 2>&1 |
grep ".*$ctty.*${sid%%"$ctty"*}"
これ/dev/null
は、検索サブシェルのいずれにも0、1、2のいずれかがcttyに接続されていない場合に機能することを示すためのものです。とにかく、それは印刷します:
/dev/pts/3: mikeserv 3342 F.... (mikeserv)zsh
さて、上記は私のマシン上の完全なパスを取得しており、ほとんどの場合、ほとんどの人にとってそうなると思います。それが失敗することも想像できます。これは大まかなヒューリスティックです。
これは他の多くの理由で失敗する可能性がありますが、セッションリーダーがすべての記述子をcttyに放棄し、仕様が許す限りsidを維持できるシステムを使用している場合、これは間違いなく役に立ちません。とはいえ、ほとんどの場合、これでかなりの見積もりが得られると思います。
もちろん、最も簡単な事はあなたが持っている場合は行うには任意のあなたのCTTYに接続記述子をちょうどです...
tty <&2
...または類似。
ps
ソリューションがほとんどのシステムをカバーしていると思います(そしてwho
それ以上は役に立ちませんps
)、おそらく識別子だけを処理するための少しだけ多くのコード( "04"など)を備えています。もっとポータブルな解決策があるのかと思っていました。