
私はPIDを含む簡単なスクリプトを書いていますecho
。
#/bin/bash
while true; do
echo $$;
sleep 0.5;
done
私は3844
ある端末でそのスクリプトを実行し(繰り返し言う)、tail
別の端末でファイル記述子を実行しようとしています。
$ tail -f /proc/3844/fd/1
画面に何も印刷せずに停止します^c
。なぜ?
さらに、すべてのSTDファイル記述子(IN / OUT / ERR)は同じ点にリンクされています。
$ ls -l /proc/3844/fd/
total 0
lrwx------ 1 mg mg 64 sie 29 13:42 0 -> /dev/pts/14
lrwx------ 1 mg mg 64 sie 29 13:42 1 -> /dev/pts/14
lrwx------ 1 mg mg 64 sie 29 13:42 2 -> /dev/pts/14
lr-x------ 1 mg mg 64 sie 29 13:42 254 -> /home/user/test.sh
lrwx------ 1 mg mg 64 sie 29 13:42 255 -> /dev/pts/14
これは普通ですか?
Ubuntu GNOME 14.04を実行しています。
この問題がULではなくSOまたはSUに属すると思われる場合は、お知らせください。
答え1
strace
1つを作成すると、tail -f
すべてが説明されます。興味深い部分:
13791 fstat(3, {st_mode=S_IFREG|0644, st_size=139, ...}) = 0
13791 fstatfs(3, {...}) = 0
13791 inotify_init() = 4
13791 inotify_add_watch(4, "/path/to/file", IN_MODIFY|IN_ATTRIB|IN_DELETE_SELF|IN_MOVE_SELF) = 1
13791 fstat(3, {st_mode=S_IFREG|0644, st_size=139, ...}) = 0
13791 read(4, 0xd981c0, 26) = -1 EINTR (Interrupted system call)
それは何ができますか?inotify
ファイルのハンドラを設定し、ファイルに何かが起こるのを待ちます。カーネルtail
がこのinotifyハンドラを介してファイルが変更されたことを示している場合(通常は追加)、tail
1)そのファイルを見つけて2)変更を読み、3)それを画面に書き込みます。
/proc/3844/fd/1
システムに/dev/pts/14
文字デバイスであるシンボリックリンクがあります。これにより、アクセスできる「メモリマップ」のようなものはありません。したがって、アクセス可能なディスクやメモリ領域がないため、コンテンツの変更についてinotifyに署名することはできません。
この文字デバイスは、実際にはネットワークソケットのように動作する仮想端末です。この仮想端末で実行されているプログラムは、デバイスに接続し(Telnetを介してTCPポートにログインしたかのように)書き込みたい内容を書き込みます。一般に、呼び出しを介して処理されるロック画面、端末制御シーケンスなど、より複雑なものもありますioctl()
。
私の考えでは、あなたはどのような方法でも仮想端末を見たいと思うようです。 Linuxで実行できますが、それほど単純ではありません。一部のネットワークプロキシと同様の機能が必要で、これらの呼び出しにはいくつかのトリッキーな使用法が必要ですioctl()
。しかし、これを可能にするツールがあります。
今はどの Debian パッケージにこれを行うことができるツールがあるのか覚えていませんが、少しだけインターネット検索をすれば簡単に見つけることができます。
拡大する:@Jajeshがここで述べたように(私に提供した場合+ 1)、ツール名はですwatch
。
拡張#2:@kelnosは単純なだけでcat /dev/pts/14
十分だと言いました。私はそれを試してみましたはい、うまくいきますが、正しくありません。これはあまり実験してみませんでしたが、その仮想ターミナルに入る出力が消えると思います。誰でもコマンドまたは元の位置に移動しますcat
が、同時に両方に移動しないでください。しかし、これは不明です。
答え2
のファイルは/dev/pts
通常のファイルではなく、仮想端末へのハンドルです。読み取りと書き込みの動作はpts
対称ではありません(つまり、作成された内容は通常のファイルやfifo /パイプのように後で読むことができます)、仮想端末を作成するプロセスによって規制されます。いくつかの一般的な動作はxtermまたはSSHまたはagettyまたは画面。制御プロセスは通常、pts
ファイルを読み取り、それを画面にレンダリングするプロセスにキーストロークを渡しますpts
。
そのためtail -f /dev/pts/14
、スクリプトを起動した端末で押されたキーが出力され、これにより端末にecho meh > /dev/pts/14
メッセージが表示されます。meh
答え3
しばらく前に私は一つを見つけました。少し解決策時々pid
プロセスがあり、わかりにくい結果を見ることができると仮定し、STDOUTに出力される内容を確認する必要性に応答します。
sudo strace -p $pid 2>&1 | grep write\(
答え4
これを行うには、tailではなく出力を見てください。
$ watch -n2 ls -l /proc/3844/fd/
これがあなたに必要なものであることを願っています。