Puedes intentar lo siguiente:
-
obtenga el PID (diga
$pid) del programa añadiendo el-popción anetstat. -
identificar la línea adecuada en el
/proc/net/tcparchivo mirando ellocal_addressy/orem_addresscampos (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 elstes01(paraESTABLISHED); -
tenga en cuenta el
inodeasociado campo (diga$inode); -
busca ese
inodeentre los descriptores de archivo en/proc/$pid/fdy 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")