ソケットをテストするときにlsofが文句を言わないようにするにはどうすればよいですか?

ソケットをテストするときにlsofが文句を言わないようにするにはどうすればよいですか?

特定のソケットを受信するプロセスがターゲットシステムfuserには存在しませんが、存在するかどうかをlsofテストする必要があります。次のコマンドを実行します。

lsof -tU /path/to/socket

リスナーのPIDをリストします。これは問題ありませんが、lsof状態で終了します1。何が間違っているかを確認するためにコマンドを変更しました。

lsof -tUV /path/to/socket

PID をもう一度リストし、次も追加します。

lsof: /path/to/socket に使用されたファイルはありません。

0「ファイルの使用」が発生したときに終了するように追加の検査を抑制する方法はありますか?するソケットでリスナーを見つけましたか?マニュアルページを見てみましたが、欲しいものが見つかりませんでした。次のように賢く使いたいです。

sock=/path/to/socket
if [[ ! -S $sock ]] || ! lsof -tU $sock &>/dev/null; then
    # task to activate socket listener
fi

答え1

最新バージョンのシステムss(Debian 10システムなどiproute2-ss190107)を使用している場合は、次のものを使用できますsslsof

sock=/path/to/socket
ino=$(stat -c 'ino:%i' "$sock") && ss -elx | grep -w "$ino"

sock=/path/to/socket
if ino=$(stat -c 'ino:%i' "$sock") && ss -elx | grep -qw "$ino"
then
   # yeah, somebody's listening on $sock
fi

ここに注目すべき2つの重要なことがあります。

  1. Unixソケットの実際のアドレスはdevice,inode数値のタプルです。パス名ではありません。ソケットファイルが次の場合動く、受信しているサーバーが何であれ、新しいパスを介してアクセスできます。ソケットファイルが次の場合削除済み他のサーバーが同じパスでリッスンする可能性があります(これがセキュリティの観点からUnixソケットへのディレクトリ権限が重要な理由です)。lsofこの問題は処理できず、不完全または誤ったデータが返される可能性があります。

  2. ssこれはそれ自体に問題があり、unix_diagnetlinkインタフェースはssLinuxカーネルで内部的に使用されている形式を使用してデバイス番号を返しますが、システムコールインタフェースで使用される形式ss(たとえば)であると仮定するstat(2)ため、上記の出力は管理されます。しかし、ある日問題を解決することを決めることもあるので、問題を解決するのは賢明ではないかもしれません。したがって、これを行う唯一のことは、それを純粋なゴミとして扱い、同じinodeを持ちますが、異なるファイルシステム上の2つのソケットファイルの危険を冒すことです。dev:ss -elxdev:上記のテストは処理できません


上記のいずれも重要でない場合は、同じように悪いことを行うことができますlsof(最初にソケットがバインドされたパスと一致する)。

sock=/path/to/socket
ss -elx | grep " $sock "

Centos 7のような古いシステムでも動作します。少なくともこれはリストだけをリストできるという利点があります。聞くソケット;-)

答え2

私がしたことは次のとおりです。

if ! [[ -S $SSH_AUTH_SOCK && -n "`ss -xa 2>/dev/null | grep -F $SSH_AUTH_SOCK 2>/dev/null`" ]]; then
    # task to activate socket listener
fi

醜いが機能的です。

関連情報