Rufen Sie die PID $piddes Programms ab, indem Sie die -pOption zu hinzufügen netstat.
die richtige Zeile in der Identifizierung /proc/net/tcpDatei , indem Sie auf den local_addressund / oder rem_addressFeldern (beachten Sie, dass sie in Hex - Format sind, insbesondere die IP - Adresse im Little-Endian - Byte - Reihenfolge ausgedrückt), auch sicherstellen, dass das stist 01(für ESTABLISHED);
beachte das zugehörige inodeFeld (sprich $inode);
Suchen Sie danach inodeunter den Dateideskriptoren in /proc/$pid/fdund fragen Sie schließlich die Dateizugriffszeit des symbolischen Links ab:
Das ist eine Grunzarbeit ... hier ist ein Skript (Stub), um die obigen Punkte zu automatisieren. Es erfordert die Remote-Adresse und gibt die Socket-Betriebszeit in Sekunden aus:
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 %T@)
[ -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")
}
In diesem Rezept wird das Alter des Prozesses angezeigt, der die TCP-Verbindung erstellt hat, nicht die Verbindung selbst.
Myroslav
@myroslav bist du sicher? Es funktioniert gegen dieses Node.js-Skript .
CYRUS
Ich habe Ihr neues Skript mit TCP-Verbindungen getestet, die von meinem Firefox auf Fedora 22 64-Bit geöffnet wurden, und ich erhalte definitiv keine "Verfügbarkeits" -Zahlen. Wenn ein neuer Socket geöffnet wird, wird die Betriebszeit "zufällig" festgelegt, normalerweise die Zeit des "jüngsten" eingerichteten Sockets.
Myroslav
@myroslav Ich verwende hier Debian (3.16.0-4-amd64), das einzige, was ich bemerke, ist, dass die angegebene Zeit in Bezug auf die Socket-Erstellung tatsächlich etwa 3 Sekunden zu spät ist. Vielleicht sind einige systemabhängige Verhaltensweisen involviert ...
cYrus
Für das Skript "$ suptime 192: 168: 120: 10 6379 Traceback (letzter Aufruf zuletzt): Datei" <string> ", Zeile 1, in <module> socket.error: Unzulässige IP-Adresszeichenfolge, die an inet_aton Address übergeben wird nicht übereinstimmen "
Ondra Žižka
4
Diese Frage war hilfreich für mich, aber ich habe festgestellt, dass ich das gesamte HEX-Zeug vermeiden muss , lsofanstatt es zu verwenden netstat:
Bei einem ${APP}vom Benutzer ausgeführten Prozess werden ${USER}alle offenen Sockets an die IP-Adresse $ {IP} zurückgegeben:
Das Skript von cYrus funktionierte für mich, aber ich musste es ein wenig korrigieren (um ein "L" in der Hex-Adresse loszuwerden und einen 4-stelligen Hex-Port zu erstellen):
Dies zeigt, wie lange der Prozess, der den Socket geöffnet hat, noch läuft. Wenn ein Prozess ständig ausgeführt wird und die Verbindung zum Netzwerk unterbrochen wird, sind diese Werte sehr unterschiedlich. +1 für Mühe
Hidralisk
1
Danke für das Skript, das in der Antwort von cYrus enthalten ist. Ich hatte Probleme beim Drucken von Duplikaten, wahrscheinlich, weil es viele Verbindungen von verschiedenen PIDs zu der angegebenen Adresse gibt. Deshalb ist hier meine verbesserte Version, die auch die PID auf jeder Ausgabezeile druckt:
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 inode of the socket
local inodes=$(awk '$4 == "01" && $3 == "'$hex_addr:$hex_port'" {print $10}' /proc/net/tcp)
[ -z "$inodes" ] && { echo 'Cannot lookup the socket(s)' 2>&1; return 1; }
# get file descriptors
for inode in $inodes; do
# get inode's file descriptor details
local fdinfo=( $(find /proc/[0-9]*/fd -lname "socket:\[$inode\]" -printf "%p %T@") )
[ -z "$fdinfo" ] && { echo 'Cannot find file descriptor' 2>&1; return 1; }
# extract pid
local fdpath=${fdinfo[0]}
local pid=${fdpath#/proc/}
pid=${pid%%/*}
# extract timestamp
local timestamp=${fdinfo[1]}
# compute the time difference
LANG=C printf 'PID: %s; Age: %s (%.2fs ago)\n' "$pid" "$(date -d @$timestamp)" $(bc <<<"$(date +%s.%N) - $timestamp")
done
}
Anmerkungen:
Bedürfnisse bc, netstat(bereitgestellt von net-toolson rhel> = 7 und ähnlichen Systemen)
Diese Frage war hilfreich für mich, aber ich habe festgestellt, dass ich das gesamte HEX-Zeug vermeiden muss ,
lsof
anstatt es zu verwendennetstat
:Bei einem
${APP}
vom Benutzer ausgeführten Prozess werden${USER}
alle offenen Sockets an die IP-Adresse $ {IP} zurückgegeben:Das
lsof
enthält dasPID
auch, aber ich bin mir nicht sicher, wie ich es bekomme und die Gerätenummer.Dies wurde unter Amazon Linux getestet.
quelle
Das Skript von cYrus funktionierte für mich, aber ich musste es ein wenig korrigieren (um ein "L" in der Hex-Adresse loszuwerden und einen 4-stelligen Hex-Port zu erstellen):
quelle
Wie wäre es mit:
Sie können den Befehl "ps" auch so anpassen, dass nur pid abgerufen wird und die Zeit mit -o beginnt, z. B .:
Dies setzt natürlich voraus, dass der Socket gestartet wurde, als der Prozess ausgeführt wurde.
quelle
Danke für das Skript, das in der Antwort von cYrus enthalten ist. Ich hatte Probleme beim Drucken von Duplikaten, wahrscheinlich, weil es viele Verbindungen von verschiedenen PIDs zu der angegebenen Adresse gibt. Deshalb ist hier meine verbesserte Version, die auch die PID auf jeder Ausgabezeile druckt:
Anmerkungen:
bc
,netstat
(bereitgestellt vonnet-tools
on rhel> = 7 und ähnlichen Systemen)quelle