GNU/Linux >> Linux の 問題 >  >> Linux

Linux でソケット接続のアップタイムを確認する方法

以下を試すことができます:

<オール>
  • PID を取得します (例:$pid ) -p を追加することによるプログラムの netstat へのオプション .

  • /proc/net/tcp の適切な行を特定する local_address を見てファイル および/または rem_address フィールド (これらは 16 進形式であることに注意してください。具体的には、IP アドレスはリトル エンディアンのバイト順で表現されます)、st 01 です (ESTABLISHED の場合) );

  • 関連する inode に注意してください フィールド (たとえば $inode );

  • その inode を検索します /proc/$pid/fd のファイル記述子の中で 最後に、シンボリック リンクのファイル アクセス時刻を照会します。

    find /proc/$pid/fd -lname "socket:\[$inode\]" -printf %t
    
  • これは面倒な作業です... 上記の点を自動化するスクリプト (スタブ) を次に示します。リモート アドレスが必要で、ソケットの稼働時間 を出力します。 秒単位:

    function suptime() {
        local addr=${1:?Specify the remote IPv4 address}
        local port=${2:?Specify the remote port number}
        # convert the provided address to hex format
        local hex_addr=$(python -c "import socket, struct; print(hex(struct.unpack('<L', socket.inet_aton('$addr'))[0])[2:10].upper().zfill(8))")
        local hex_port=$(python -c "print(hex($port)[2:].upper().zfill(4))")
        # get the PID of the owner process
        local pid=$(netstat -ntp 2>/dev/null | awk '$6 == "ESTABLISHED" && $5 == "'$addr:$port'"{sub("/.*", "", $7); print $7}')
        [ -z "$pid" ] && { echo 'Address does not match' 2>&1; return 1; }
        # get the inode of the socket
        local inode=$(awk '$4 == "01" && $3 == "'$hex_addr:$hex_port'" {print $10}' /proc/net/tcp)
        [ -z "$inode" ] && { echo 'Cannot lookup the socket' 2>&1; return 1; }
        # query the inode status change time
        local timestamp=$(find /proc/$pid/fd -lname "socket:\[$inode\]" -printf %[email protected])
        [ -z "$timestamp" ] && { echo 'Cannot fetch the timestamp' 2>&1; return 1; }
        # compute the time difference
        LANG=C printf '%s (%.2fs ago)\n' "$(date -d @$timestamp)" $(bc <<<"$(date +%s.%N) - $timestamp")
    }
    

    (Alex の修正に感謝します)

    例:

    $ suptime 93.184.216.34 80
    Thu Dec 24 16:22:58 CET 2015 (46.12s ago)
    

    この質問は役に立ちましたが、 lsof を使用して見つけました netstat の代わりに すべての HEX を避けさせてください:

    プロセス ${APP} の場合 ユーザー ${USER} によって実行されます の場合、次のコードは、開いているすべてのソケットを IP アドレス ${IP} に返します:

    PEEID=$(sudo pgrep -u ${USER} ${APP}) && for i in `sudo lsof -anP -i -u logstash | grep ${IP} | awk '{print $6}'` ; do echo "${device} time" ; sudo find /proc/${PEEID}/fd -lname "socket:\[${device}\]" -printf %t 2> /dev/null  ; echo  ;  done
    

    lsof PID を含む でも、それを取得する方法とデバイス番号がわかりません.

    これは Amazon Linux でテストされました。


    cYrus のスクリプトはうまくいきましたが、少し修正する必要がありました (16 進アドレスの「L」を取り除き、ポートを 4 桁の 16 進にするため):

    --- suptime.orig    2015-08-20 15:46:12.896652464 +0200
    +++ suptime 2015-08-20 15:47:48.560074728 +0200
    @@ -7,8 +7,8 @@
         hex_addr=$(python -c "
     import socket, struct;
     print hex(struct.unpack('<L',
    -socket.inet_aton('$addr'))[0])[2:].upper().zfill(8)")
    -    hex_port=$(python -c "print hex($port)[2:].upper()")
    +socket.inet_aton('$addr'))[0])[2:10].upper().zfill(8)")
    +    hex_port=$(python -c "print hex($port)[2:].upper().zfill(4)")
         inode=$(awk '$3 == "'$hex_addr:$hex_port'" {print $10}' /proc/net/tcp)
         time=$(find /proc/$pid/fd -lname "socket:\[$inode\]" -printf %[email protected])
         LANG=C printf '%.2fs' $(bc <<<"$(date +%s.%N) - $time")
    

    Linux
    1. Linuxgrepコマンドの使用方法

    2. LinuxTouchコマンドの使用方法+例

    3. Linux –どのモジュールがカーネルを汚染しているかを判断する方法は?

    1. Linux サーバーで Spfile がいつ作成されたかを確認する方法

    2. Linux シェルで 16 進数を ASCII 文字に変換する方法は?

    3. time コマンドの出力を Linux のファイルにリダイレクトする方法は?

    1. Linuxがメインフレームに登場した経緯

    2. 長時間実行されている Linux プロセスの開始時刻を取得するには?

    3. Linux のコマンドラインから socket.io websocket にメッセージを送信するにはどうすればよいですか?