Puoi provare quanto segue:
-
ottieni il PID (ad esempio
$pid
) del programma aggiungendo il-p
opzione anetstat
. -
identificare la riga corretta nel
/proc/net/tcp
guardando il filelocal_address
e/orem_address
campi (nota che sono in formato esadecimale, in particolare l'indirizzo IP è espresso in ordine di byte little-endian), assicurati anche che ilst
è01
(perESTABLISHED
); -
nota il
inode
associato campo (ad esempio$inode
); -
cerca quel
inode
tra i descrittori di file in/proc/$pid/fd
e infine interrogare il tempo di accesso al file del collegamento simbolico:find /proc/$pid/fd -lname "socket:\[$inode\]" -printf %t
È un duro lavoro... ecco uno script (stub) per automatizzare i punti precedenti, richiede l'indirizzo remoto e stampa il tempo di attività del socket in secondi:
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")
}
(Modifica, grazie ad Alex per le correzioni)
Esempio:
$ suptime 93.184.216.34 80
Thu Dec 24 16:22:58 CET 2015 (46.12s ago)
Questa domanda mi è stata utile, ma ho trovato l'uso di lsof
invece di netstat
fammi evitare tutte le cose HEX:
Per un processo ${APP}
eseguito dall'utente ${USER}
, quanto segue restituisce tutti i socket aperti all'indirizzo 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
Il lsof
contiene il PID
anche, ma non sono sicuro di come ottenerlo e il numero del dispositivo.
Questo è stato testato su Amazon Linux.
Lo script di cYrus ha funzionato per me, ma ho dovuto correggerlo un po' (per eliminare una "L" nell'indirizzo esadecimale e rendere la porta un esadecimale a 4 cifre):
--- 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")