Puedes intentar lo siguiente:
-
obtenga el PID (diga
$pid
) del programa añadiendo el-p
opción anetstat
. -
identificar la línea adecuada en el
/proc/net/tcp
archivo mirando ellocal_address
y/orem_address
campos (tenga en cuenta que están en formato hexadecimal, específicamente la dirección IP se expresa en orden de bytes little-endian), también asegúrese de que elst
es01
(paraESTABLISHED
); -
tenga en cuenta el
inode
asociado campo (diga$inode
); -
busca ese
inode
entre los descriptores de archivo en/proc/$pid/fd
y finalmente consultar el tiempo de acceso al archivo del enlace simbólico:find /proc/$pid/fd -lname "socket:\[$inode\]" -printf %t
Eso es un trabajo duro... aquí hay un script (stub) para automatizar los puntos anteriores, requiere la dirección remota e imprime el tiempo de actividad del socket en segundos:
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")
}
(Editar gracias a Alex por las correcciones)
Ejemplo:
$ suptime 93.184.216.34 80
Thu Dec 24 16:22:58 CET 2015 (46.12s ago)
Esta pregunta fue útil para mí, pero encontré usando lsof
en lugar de netstat
déjame evitar todas las cosas HEX:
Para un proceso ${APP}
ejecutado por el usuario ${USER}
, lo siguiente devuelve todos los sockets abiertos a la dirección 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
El lsof
contiene el PID
también, pero no estoy seguro de cómo obtenerlo y el número de dispositivo.
Esto fue probado en Amazon Linux.
El script de cYrus funcionó para mí, pero tuve que arreglarlo un poco (para deshacerme de una "L" en la dirección hexadecimal y convertir el puerto en un hexadecimal de 4 dígitos):
--- 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")