Sie können Folgendes versuchen:
-
Holen Sie sich die PID (sagen Sie
$pid
) des Programms durch Hinzufügen des-p
Option zunetstat
. -
Identifizieren Sie die richtige Zeile in
/proc/net/tcp
Datei, indem Sie sich dielocal_address
ansehen und/oderrem_address
Felder (beachten Sie, dass sie im Hex-Format vorliegen, insbesondere die IP-Adresse wird in Little-Endian-Byte-Reihenfolge ausgedrückt), stellen Sie außerdem sicher, dassst
ist01
(fürESTABLISHED
); -
Beachten Sie den zugehörigen
inode
Feld (z. B.$inode
); -
suche nach diesem
inode
unter den Dateideskriptoren in/proc/$pid/fd
und schließlich die Dateizugriffszeit des symbolischen Links abfragen:find /proc/$pid/fd -lname "socket:\[$inode\]" -printf %t
Das ist eine Grunzerarbeit... hier ist ein Skript (Stub), um die obigen Punkte zu automatisieren, es erfordert die entfernte Adresse und es gibt die Socket-Betriebszeit aus in Sekunden:
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")
}
(Bearbeiten danke an Alex für die Korrekturen)
Beispiel:
$ suptime 93.184.216.34 80
Thu Dec 24 16:22:58 CET 2015 (46.12s ago)
Diese Frage war hilfreich für mich, aber ich fand die Verwendung von lsof
statt netstat
Lassen Sie mich das ganze HEX-Zeug vermeiden:
Für einen Prozess ${APP}
ausgeführt von Benutzer ${USER}
, gibt der folgende Befehl alle offenen Sockets an die IP-Adresse ${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
Die lsof
enthält den PID
auch, aber ich bin mir nicht sicher, wie ich es und die Gerätenummer bekomme.
Dies wurde auf Amazon Linux getestet.
Das Skript von cYrus hat für mich funktioniert, aber ich musste es ein wenig korrigieren (um ein "L" in der Hex-Adresse loszuwerden und den Port zu einem 4-stelligen Hex zu machen):
--- 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")