今日、私は起動時にファイル記述子を検証するツールでバグを見つけました。問題は追加の接続があることですpts
。
# In one console I start `cat`
linux $ cat >/tmp/test
# In another console I search for `cat`'s process ID
linux $ ps -ef | grep cat
alexis 34462 25012 0 11:58 pts/17 00:00:00 cat
# Now check the file descriptors:
linux $ ls -l /proc/34462/fd
total 0
lrwx------ 1 alexis alexis 64 Sep 23 11:59 0 -> /dev/pts/17
l-wx------ 1 alexis alexis 64 Sep 23 11:59 1 -> /tmp/test
lrwx------ 1 alexis alexis 64 Sep 23 11:59 2 -> /dev/pts/17
lrwx------ 1 alexis alexis 64 Sep 23 11:59 6 -> /dev/pts/17
ご覧のとおり、stdin
ターゲットファイル名に設定されています/tmp/test
。予想通り、0と2はpts
。
それでは、6は何ですか?
私の考えでは、これは私のRails環境から来たようです。スクリプトrvm
は私のコンソールでいくつかの「魔法」を実行し、名前付きcd
ファイルを含むディレクトリに移動するとGemfile
それを検出します。つまり、これは単なるcd
エイリアスにすぎないと思います。それがどこから来たのか、どの機能を提供するのかをテストするにはどうすればよいですか?
. ~/.rvm/scripts/rvm .
アップデート:RVM init()をコメントアウトした後に新しいコンソールを開くと、追加の疑似ターミナルファイル記述子を取得できないことがわかります。それでも、彼らがどのようにこれを行うことができるのか疑問に思います。
答え1
RVMが起動したら、現在接続されている標準エラーの新しいファイル記述子を開きます。したがって、RVM環境では、ファイル記述子6がRVMログ出力です。このようにして、RVMは標準エラーがリダイレクトされたかどうかにかかわらず、ファイル記述子6に出力を書き込むことで、同じ場所に出力を書き込むことができます。
ファイル記述子が開いています。最後にscripts/functions/logging
。
exec 6>&2
これexec
組み込み機能はパラメータを使用しませんが、シェルプロセス内で実行されるリダイレクトを使用します。したがって、exec 6>&2
ファイルディスクリプタ6をシェルのファイルディスクリプタ2に開きます。シェルから起動されたプログラムはこのファイル記述子を継承します。
RVMが何かを記録しようとすると(通常)ファイル記述子6に出力されます。こんなことが起こったrvm_error
機能、例えば。
たとえば、端末で起動されたRVM環境で実行される次のコードは、「Stuff gone」を端末myfile.log
に書き込みます。Hello
f () {
…
echo >&2 "Stuff happened"
rvm_error "Hello"
}
f 2>myfile.log
答え2
この特殊ファイルには、現在のスレッドfutexコンテキストハンドルが含まれています。