출력의 두 번째 열을 geoiplookup에 전달하는 방법을 찾고 있습니다. 가급적이면 같은 줄에 있지만 반드시 그런 것은 아닙니다. 그게 내가 소집할 수 있는 최선이야. 사용 가능하지만 아쉽게도 geoiplookup 결과는 연결 목록 아래에 있습니다. 더 포괄적인 결과를 원합니다. 누구든지 개선 사항을 제안할 수 있다면 환영합니다.
ns () {
echo ""
while sleep 1; do
lsof -Pi |
grep ESTABLISHED |
sed "s/[^:]*$//g" |
sed "s/^[^:]*//g" |
sed "s/://g" |
sed "s/->/\t/g" |
grep -v localdomain$ |
tee >(for x in `grep -o "\S*$"`; do geoiplookup $x | sed "s/GeoIP.*: /\t/g"; done)
done
}
현재 결과는 다음과 같습니다.
<Port> <URL or IP if no reverse available #1>
<Port> <URL or IP if no reverse available #2>
<geoiplookup trimmed result #1>
<geoiplookup trimmed result #2>
답변1
이것이 바로 RobotJohnny 덕분에 제가 얻은 결과입니다.
ns () {
echo ""
while sleep 1; do
IFS=$'\n'
for line in $(lsof -Pi |
grep ESTABLISHED |
grep -ve "localdomain:[0-9]* .EST" \
-e "search.msn.com:[0-9]* .EST" \
-e "spider.yandex.com:[0-9]* .EST" \
-e "google.com:[0-9]* .EST"); do
cmdpidusr=$(echo $line | awk -v OFS='\t' '{print $1, $2, $3}')
node=$(echo $line | awk '{print $8}')
ipadd=$(echo $line | awk '{print $9}' | cut -d ">" -f 2 | cut -d ":" -f 1)
port=$(echo $line | awk '{print $9}' | cut -d ">" -f 1 | cut -d ":" -f 2 | cut -d "-" -f 1)
geoip=$(geoiplookup $ipadd | sed "s/GeoIP.*: \S* //g")
echo -e "$cmdpidusr\t$node\t$port\t$ipadd\t$geoip" | sed "s/\s*resolve hostname.*//g" | grep -v root
done | column -t -s $'\t' | sed "s/ \s*/ /g"
unset IFS
done
}
답변2
개선 측면에서는 lsof -Pi
관심 있는 데이터에 따라 다릅니다.
다음은 명령, PID, 사용자, 노드, IP, 포트 및 geoip를 인쇄하는 "한 줄"입니다(별로...).
echo -e "COMMAND\tPID\tUSER\tNODE\tIP\tPORT\tGEO"; IFS=$'\n'; for line in $(lsof -Pi | grep ESTABLISHED | grep -E '*(([0-9]{1,3})\.){3}([0-9]{1,3}){1})*'); do cmdpidusr=$(echo $line | awk '{print $1,$2,$3}'); node=$(echo $line | awk '{print $8}'); ipadd=$(echo $line | awk '{print $9}' | cut -d ">" -f 2 | cut -d ":" -f 1); port=$(echo $line | awk '{print $9}' | cut -d ">" -f 2 | cut -d ":" -f 2); geoip=$(geoiplookup $ipadd | cut -d : -f 2); echo -e "$cmdpidusr\t$node\t$ipadd\t$port\t$geoip"; done | column -t; unset IFS
예를 들어 출력은 다음과 같습니다.
┌─[root@Fedora]─[~]─[10:22 am]
└─[$]› echo -e "COMMAND\tPID\tUSER\tNODE\tIP\tPORT\tGEO"; IFS=$'\n'; for line in $(lsof -Pi | grep ESTABLISHED | grep -E '*(([0-9]{1,3})\.){3}([0-9]{1,3}){1})*'); do cmdpidusr=$(echo $line | awk '{print $1,$2,$3}'); node=$(echo $line | awk '{print $8}'); ipadd=$(echo $line | awk '{print $9}' | cut -d ">" -f 2 | cut -d ":" -f 1); port=$(echo $line | awk '{print $9}' | cut -d ">" -f 2 | cut -d ":" -f 2); geoip=$(geoiplookup $ipadd | cut -d : -f 2); echo -e "$cmdpidusr\t$node\t$ipadd\t$port\t$geoip"; done | column -t; unset IFS
COMMAND PID USER NODE IP PORT GEO
synergys 16444 user1 TCP 172.1.1.1 59116 IP Address not found
ssh 21557 root TCP 1.2.3.4 2291 GB, United Kingdom
당신이 그것을 당신의 기능이나 다른 것으로 원한다면 .bashrc
조금 더 멋지게 보이게 만들 수 있습니다.
iplookup() {
echo -e "COMMAND\tPID\tUSER\tNODE\tIP\tPORT\tGEO"
IFS=$'\n' # set field separator to new line
for line in $(lsof -Pi | grep ESTABLISHED | grep -E '*(([0-9]{1,3})\.){3}([0-9]{1,3}){1})*'); do # this is just a regex grep to pull lines with valid IPv4 addresses only
cmdpidusr=$(echo $line | awk '{print $1,$2,$3}')
node=$(echo $line | awk '{print $8}')
ipadd=$(echo $line | awk '{print $9}' | cut -d ">" -f 2 | cut -d ":" -f 1)
port=$(echo $line | awk '{print $9}' | cut -d ">" -f 2 | cut -d ":" -f 2)
geoip=$(geoiplookup $ipadd | cut -d : -f 2)
echo -e "$cmdpidusr\t$node\t$ipadd\t$port\t$geoip"
done | column -t # organise the columns
unset IFS # set field separator to default
}
IPv6 조회에는 이를 사용해야 하므로 이는 적용되지 않습니다 geoiplookup6
. IP 유형을 확인하는 조건을 추가한 후 geoiplookup/6
출력에 따라 실행할 수 있습니다.예를 들어:
...
type=$(echo $line | awk '{print $5}')
if [ "$type" = "IPv4" ]; then
geoip=$(geoiplookup $ipadd | cut -d : -f 2)
else
geoip=$(geoiplookup6 $ipadd | cut -d : -f 2)
fi
...
하지만 위 코드와 함께 사용하려면 IPv4 정규식을 제거하거나 IPv6을 포함하도록 추가해야 합니다.