Anda dapat mencoba yang berikut ini:
-
dapatkan PID (misalkan
$pid
) dari program dengan menambahkan-p
opsi untuknetstat
. -
mengidentifikasi baris yang tepat di
/proc/net/tcp
file dengan melihatlocal_address
dan/ataurem_address
bidang (perhatikan bahwa mereka dalam format hex, khususnya alamat IP dinyatakan dalam urutan byte little-endian), pastikan juga bahwast
adalah01
(untukESTABLISHED
); -
perhatikan
inode
yang terkait bidang (misalkan$inode
); -
cari
inode
itu di antara deskriptor file di/proc/$pid/fd
dan terakhir menanyakan waktu akses file dari tautan simbolik:find /proc/$pid/fd -lname "socket:\[$inode\]" -printf %t
Itu adalah pekerjaan kasar ... inilah skrip (rintisan) untuk mengotomatiskan poin-poin di atas, ini memerlukan alamat jarak jauh dan mencetak waktu aktif soket dalam hitungan detik:
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")
}
(Edit terima kasih kepada Alex untuk perbaikannya)
Contoh:
$ suptime 93.184.216.34 80
Thu Dec 24 16:22:58 CET 2015 (46.12s ago)
Pertanyaan ini sangat membantu saya, tetapi saya menemukan menggunakan lsof
bukannya netstat
biarkan saya menghindari semua hal HEX:
Untuk proses ${APP}
dijalankan oleh pengguna ${USER}
, berikut mengembalikan semua soket terbuka ke alamat 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
lsof
berisi PID
juga, tapi saya tidak yakin bagaimana cara mendapatkannya dan nomor perangkatnya.
Ini telah diuji di Amazon Linux.
Skrip oleh cYrus bekerja untuk saya tetapi saya harus memperbaikinya sedikit (untuk menghilangkan "L" di alamat hex dan membuat port menjadi hex 4 digit):
--- 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")