كيف يمكنني كتابة برنامج نصي Linux Bash يخبرني بأجهزة الكمبيوتر الموجودة في LAN الخاصة بي؟

StackOverflow https://stackoverflow.com/questions/733418

  •  06-09-2019
  •  | 
  •  

سؤال

كيف يمكنني كتابة برنامج نصي Linux Bash يخبرني بأجهزة الكمبيوتر الموجودة في LAN الخاصة بي؟

من شأنه أن يساعد إذا استطعت إعطائها كمدخلات من IP.

هل كانت مفيدة؟

المحلول

أود أن أقترح باستخدام علامة Ping-Scan Nmap،

$ nmap -sn 192.168.1.60-70

Starting Nmap 4.11 ( http://www.insecure.org/nmap/ ) at 2009-04-09 20:13 BST
Host machine1.home (192.168.1.64) appears to be up.
Host machine2.home (192.168.1.65) appears to be up.
Nmap finished: 11 IP addresses (2 hosts up) scanned in 0.235 seconds

ومع ذلك، إذا كنت ترغب في كتابة ذلك بنفسك (وهو أمر عادل بما فيه الكفاية)، فهذه الطريقة التي سأفعلها:

for ip in 192.168.1.{1..10}; do ping -c 1 -t 1 $ip > /dev/null && echo "${ip} is up"; done

.. وشرح لكل بت من الأمر أعلاه:

إنشاء قائمة عناوين IP

يمكنك استعمال ال {1..10} بناء جملة لتوليد قائمة بالأرقام، على سبيل المثال ..

$ echo {1..10}
1 2 3 4 5 6 7 8 9 10

(من المفيد أيضا للأشياء مثل mkdir {dir1,dir2}/{sub1,sub2} - مما يجعل dir1 و dir2, كل تحتوي على ذلك sub1 و sub2)

لذلك، لتوليد قائمة IP، كنا نفعل شيئا مثل

$ echo 192.168.1.{1..10}
192.168.1.1 192.168.1.2 [...] 192.168.1.10

حلقات

لحلقة على شيء في باش، تستخدم for:

$ for thingy in 1 2 3; do echo $thingy; done
1
2
3

تاتينج

بعد ذلك، إلى Ping .. يتراوح أمر Ping قليلا مع أنظمة التشغيل المختلفة، وتوزيعات / إصدارات مختلفة (أنا أستخدم OS X حاليا)

افتراضيا (مرة أخرى، في إصدار OS X من ping) سوف بينغ حتى توقف، والتي لن تعمل لهذا، لذلك ping -c 1 سيحاول فقط إرسال حزمة واحدة، والتي يجب أن تكون كافية لتحديد ما إذا كانت الجهاز مؤخرا.

مشكلة أخرى هي قيمة المهلة، والتي يبدو أنها 11 ثانية على هذا الإصدار من بينغ .. لقد تغيرت باستخدام -t علم. يجب أن تكون ثانية واحدة كافية لمعرفة ما إذا كانت الآلة على الشبكة المحلية حية أم لا.

لذلك، أمر Ping نحن سوف نستخدمه هو ..

$ ping -c 1 -t 1 192.168.1.1
PING 192.168.1.1 (192.168.1.1): 56 data bytes

--- 192.168.1.1 ping statistics ---
1 packets transmitted, 0 packets received, 100% packet loss

التحقق من نتيجة بينغ

بعد ذلك، نحتاج إلى معرفة ما إذا كان الجهاز أجاب أم لا ..

يمكننا استخدام && المشغل لتشغيل أمر إذا نجح الأول، على سبيل المثال:

$ echo && echo "It works"

It works
$ nonexistantcommand && echo "This should not echo"
-bash: nonexistantcommand: command not found

جيد، لذلك يمكننا أن نفعل ..

بينغ -c 1 -t 1 192.168.1.1 && echo "192.168.1.1 هو!"

والطريقة الأخرى هي استخدام رمز الخروج من بينغ .. سوف يخرج الأمر ping مع رمز الخروج 0 (النجاح) إذا كان يعمل، ورمز غير صفر إذا فشل. في BASH تحصل على آخر الأوامر الخروج من التعليمات البرمجية مع المتغير $?

لذلك، للتحقق مما إذا كان الأمر يعمل، كنا نفعل ..

ping -c 1 -t 1 192.168.1.1;
if [ $? -eq 0 ]; then
    echo "192.168.1.1 is up";
else 
    echo "ip is down";
fi

إخفاء الناتج بينغ

آخر شيء، لا نحتاج إلى رؤية إخراج Ping، حتى نتمكن من إعادة توجيه stdout ل /dev/null مع ال > إعادة التوجيه، على سبيل المثال:

$ ping -c 1 -t 1 192.168.1.1 > /dev/null && echo "IP is up"
IP is up

وإعادة توجيه stderr (تجاهل ping: sendto: Host is down الرسائل)، أنت تستخدم 2> - علي سبيل المثال:

$ errorcausingcommand
-bash: errorcausingcommand: command not found
$ errorcausingcommand 2> /dev/null
$

النص

لذلك، للجمع بين كل ذلك ..

for ip in 192.168.1.{1..10}; do  # for loop and the {} operator
    ping -c 1 -t 1 192.168.1.1 > /dev/null 2> /dev/null  # ping and discard output
    if [ $? -eq 0 ]; then  # check the exit code
        echo "${ip} is up" # display the output
        # you could send this to a log file by using the >>pinglog.txt redirect
    else
        echo "${ip} is down"
    fi
done

أو باستخدام && الطريقة، في بطانة واحدة:

for ip in 192.168.1.{1..10}; do ping -c 1 -t 1 $ip > /dev/null && echo "${ip} is up"; done

مشكلة

إنه بطيء .. يأخذ كل أمر بينغ حوالي 1 ثانية (نظرا لأننا وضعنا علامة مهلة -T إلى ثانية واحدة). لا يمكن تشغيل أمر Ping One فقط في وقت واحد .. الطريقة الواضحة حول هذا هو استخدام الخيوط، حتى تتمكن من تشغيل أوامر متزامنة، ولكن هذا يتجاوز ما يجب عليك استخدام bash for ..

"Python المواضيع - مثال واحد" يشرح كيفية استخدام وحدة خيوط Python لكتابة Ping'er متعدد الخيوط .. على الرغم من أنه في هذه المرحلة، أود أن أقترح مرة أخرى باستخدام nmap -sn..

نصائح أخرى

في العالم الحقيقي، يمكنك استخدام NMAP. للحصول على ما تريد.

nmap -sn 10.1.1.1-255

هذا سوف يعزز كل العناوين في النطاق 10.1.1.1 إلى 10.1.1.255 وأعلمك بأي منها الإجابة.

بالطبع، إذا كنت ترغب في الواقع في القيام بذلك كممارسة باش، يمكنك تشغيل Ping لكل عنوان وتحليل الإخراج، ولكن هذه قصة أخرى كاملة.

على افتراض شبكة بلدي هو 10.10.0.0/24، إذا قمت بتشغيل Ping على عنوان البث مثل

ping -b 10.10.0.255

سأحصل على إجابة من جميع أجهزة الكمبيوتر على هذه الشبكة التي لم تمنع منفذ ICMP Ping.

64 bytes from 10.10.0.6: icmp_seq=1 ttl=64 time=0.000 ms
64 bytes from 10.10.0.12: icmp_seq=1 ttl=64 time=0.000 ms 
64 bytes from 10.10.0.71: icmp_seq=1 ttl=255 time=0.000 ms 

لذلك عليك فقط استخراج العمود الرابع، مع AWK على سبيل المثال:

ping -b 10.10.0.255 | grep 'bytes from' | awk '{ print $4 }'

10.10.0.12:
10.10.0.6:
10.10.0.71:
10.10.0.95:

حسنا، سوف تحصل على مكررة، وقد تحتاج إلى إزالة ":".

تحرير من التعليقات: يحد خيار -c يحد من عدد الأصوات نظرا لأن البرنامج النصي سينتهي، يمكننا أيضا أن نحد نفسك على IPS الفريد

ping -c 5 -b 10.10.0.255 | grep 'bytes from' | awk '{ print $4 }' | sort | uniq

يوجد ايضا فاسق:

fping -g 192.168.1.0/24

أو:

fping -g 192.168.1.0 192.168.1.255

أو عرض المضيفين فقط على قيد الحياة:

fping -ag 192.168.1.0/24

يستضيف الأصوات بالتوازي حتى الفحص سريع جدا. أنا لا أعرف التوزيع الذي يشمل fping في التثبيت الافتراضي، ولكن في معظم التوزيعات، يمكنك الحصول عليها من خلال إدارة الحزمة.

أيضا باستخدام طريقة "Ping the Broadcast عنوان" المدببة بواسطة Chburd، يجب أن يقوم هذا الأنبوب بالخدعة لك:

ping -c 5 -b 10.11.255.255 | sed -n 's/.* \([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\).*/\1/p' | sort | uniq

بالطبع، يجب عليك تغيير عنوان البث إلى شبكة شبكتك.

فقط للمتعة، إليك بديل

     #!/bin/bash
     nmap -sP 192.168.1.0/24 > /dev/null 2>&1 && arp -an | grep -v incomplete | awk '{print$2}' | sed -e s,\(,, | sed -e s,\),,

إذا كنت تقصر من نفسك فقط بعد تغيير الثمانية الأخيرة، فيجب أن يقوم هذا البرنامج النصي بذلك. يجب أن يكون واضحا إلى حد ما كيفية تمديده من واحد إلى عدة وثتمات.

#! / BIN / BASH BASE = 1 دولار بدء = 2 دولار = 6 دولارات = 3 دولارات = بدء التشغيل بينما [$ Counter -L $ end] Do IP = $ قاعدة. $ counter إذا كان بينغ -qc 2 $ art IP ثم صدى "$ IP يستجيب" فاي = $ (($ counter + 1))

كما أشارت الملصقات الأخرى، nmap هي الطريقة للذهاب، ولكن إليك كيفية القيام بما يعادل فحص بينغ في باش. لن أستخدم البث بينغ، حيث يتم تكوين الكثير من الأنظمة بعدم الرد على بث ICMP في الوقت الحاضر.

for i in $(seq 1 254); do
    host="192.168.100.$i"
    ping -c 1 -W 1 $host &> /dev/null
    echo -n "Host $host is "
    test $? -eq 0 && echo "up" || echo "down"
done
#!/bin/bash
#Get the ip address for the range
ip=$(/sbin/ifconfig eth0 | grep 'inet addr:' | cut -d: -f2 | awk '{ print $1}' | cut -d"." -f1,2,3)

# ping test and list the hosts and echo the info

for range in $ip ; do  [ $? -eq 0 ] && ping -c 1 -w 1 $range > /dev/null 2> /dev/null && echo "Node $range is up" 
done

على الرغم من أن سؤال قديم، إلا أنه لا يزال يبدو مهما (مهما على الأقل بما يكفي بالنسبة لي للتعامل مع هذا). يعتمد البرنامج النصي الخاص بي على NMAP أيضا، لذلك لا يوجد شيء خاص هنا باستثناء أن OU يمكن أن تحدد الواجهة التي تريد مسحها ويتم إنشاء نطاق IP تلقائيا (على الأقل نوعا).

هذا هو ما خطرت لي

#!/bin/bash
#Script for scanning the (local) network for other computers 

command -v nmap >/dev/null 2>&1 || { echo "I require nmap but it's not installed. Aborting." >&2; exit 1; }

if [ -n ""$@"" ];  then
    ip=$(/sbin/ifconfig $1 | grep 'inet '  | awk '{ print $2}' | cut -d"." -f1,2,3 )
    nmap -sP $ip.1-255
else
    echo -e "\nThis is a script for scanning the (local) network for other computers.\n"
    echo "Enter Interface as parameter like this:"
    echo -e "\t./scannetwork.sh $(ifconfig -lu | awk '{print $2}')\n"

    echo "Possible interfaces which are up are: "   
    for i in $(ifconfig -lu)
    do
        echo -e "\033[32m \t $i \033[39;49m"
    done

    echo "Interfaces which could be used but are down at the moment: "
    for i in $(ifconfig -ld)
    do
        echo -e "\033[31m \t $i \033[39;49m"
    done
    echo
fi

ملاحظة واحدة: يتم إنشاء هذا البرنامج النصي على OSX، لذلك قد يكون هناك بعض التغييرات في بيئات Linux.

إذا كنت ترغب في تقديم قائمة من المضيفين، فيمكن القيام بذلك باستخدام NMAP و GREP و AWK.

تثبيت NMAP:

$ sudo apt-get install nmap

إنشاء ملف HostCheck.Sh مثل هذا:

HostCheck.Sh.

#!/bin/bash

nmap -sP -iL hostlist -oG pingscan > /dev/null
grep Up pingscan | awk '{print $2}' > uplist
grep Down pingscan | awk '{print $2}' > downlist

-SP: Ping Scan - انتقل إلى أبعد من تحديد إذا كان المضيف عبر الإنترنت

-لا: المدخلات من قائمة المضيفين / الشبكات

--وج: نتائج فحص الإخراج بتنسيق Grepable، إلى اسم الملف المحدد.

/ dev / null: يتجاهل الناتج

تغيير إذن الوصول:

$ chmod 775 hostcheck.sh

إنشاء قائمة HostList مع قائمة المضيفين المراد التحقق منها (اسم المضيف أو IP):

قائمة المضيف (مثال)

192.168.1.1-5
192.168.1.101
192.168.1.123

192.168.1.1-5 هو مجموعة من IPS

تشغيل البرنامج النصي:

./hostcheck.sh hostfile.

سيتم إنشاؤه ملفات Pingscan مع جميع المعلومات، والتقاعيات مع المضيفين عبر الإنترنت (UP) وإدراجها مع المضيفين دون اتصال بالإنترنت (لأسفل).

uplist (مثال)

192.168.1.1
192.168.1.2
192.168.1.3
192.168.1.4
192.168.1.101

القائمة أسفل (مثال)

192.168.1.5
192.168.1.123

بعض الآلات لا تجيب بين الأصوات (مثل جدران الحماية).

إذا كنت تريد فقط الشبكة المحلية، يمكنك استخدام هذا الأمر:

(for n in $(seq 1 254);do sudo arping -c1 10.0.0.$n &  done ; wait) | grep reply | grep --color -E '([0-9]+\.){3}[0-9]+'

تفسيرات جزء!

  1. arping هو أمر يرسل طلبات ARP. إنه موجود على معظم لينكس.

مثال:

sudo arping -c1 10.0.0.14

Sudo ليس من الضروري إذا كنت جذر ofc.

  • 10.0.0.14 : IP الذي تريد اختباره
  • -c1 : إرسال طلب واحد فقط.

  1. &: شخصية "I- لا تريد الانتظار"

هذه هي شخصية مفيدة حقا تعطيك إمكانية تشغيل أمر في عملية فرعية دون انتظار إنهاء (مثل موضوع)


  1. ال for حلقة هنا لتثير كل من عناوين IP 255. يستخدم seq أمر لسرد جميع الأرقام.

  1. wait: بعد أن أطلقنا طلباتنا، نريد أن نرى ما إذا كانت هناك بعض الردود. للقيام بذلك wait بعد الحلقة.wait يشبه الوظيفة join() بلغات أخرى.

  1. (): الأقواس هنا لتفسير جميع المخرجات كنص حتى نتمكن من إعطائها grep

  1. grep: نريد فقط أن نرى الردود. Grep الثاني هو هنا فقط لتسليط الضوء على IPS.

هذر

تحرير 20150417: تحديث ماكسي!

الجزء السيئ من الحل هو أنه طباعة جميع النتائج في النهاية. ذلك لأن GREP لديها مخزن مؤقت كبير بما يكفي لوضع بعض الخطوط في الداخل. الحل هو إضافة --line-buffered إلى أول GREP. مثل ذلك:

(for n in $(seq 1 254);do sudo arping -c1 10.0.0.$n &  done ; wait) | grep --line-buffered reply | grep --color -E '([0-9]+\.){3}[0-9]+'
#!/bin/bash

for ((n=0 ; n < 30 ; n+=1))
do
    ip=10.1.1.$n
    if ping -c 1 -w 1 $ip > /dev/null 2> /dev/null >> /etc/logping.txt; then  
        echo "${ip} is up" # output up
        # sintax >> /etc/logping.txt log with .txt format
    else
        echo "${ip} is down" # output down
    fi
done

يدير التعليمات البرمجية التالية (الشر) أكثر من ضعف طريقة NMAP

for i in {1..254} ;do (ping 192.168.1.$i -c 1 -w 5  >/dev/null && echo "192.168.1.$i" &) ;done

يستغرق حوالي 10 ثانية، حيث nmap القياسية

nmap -sP 192.168.1.1-254

يستغرق 25 ثانية ...

حسنا، هذا جزء من نص لي.

Ship.Sh. 🚢 شبكة بسيطة ومفيدة عنوان 🔎 multitool مع الكثير من الميزات 🌊

Bingings Network، يعرض المضيفين عبر الإنترنت على تلك الشبكة مع عنوان IP الخاص بهم المحلي وعنوان MAC

لا يتطلب أي تحرير. يحتاج إلى إذن الجذر لتشغيل.

GOOGLE_DNS="8.8.8.8"
ONLINE_INTERFACE=$(ip route get "${GOOGLE_DNS}" | awk -F 'dev ' 'NR == 1 {split($2, a, " "); print a[1]}')
NETWORK_IP=$(ip route | awk "/${ONLINE_INTERFACE}/ && /src/ {print \$1}" | cut --fields=1 --delimiter="/")
NETWORK_IP_CIDR=$(ip route | awk "/${ONLINE_INTERFACE}/ && /src/ {print \$1}")
FILTERED_IP=$(echo "${NETWORK_IP}" | awk 'BEGIN{FS=OFS="."} NF--')

ip -statistics neighbour flush all &>/dev/null

echo -ne "Pinging ${NETWORK_IP_CIDR}, please wait ..."
for HOST in {1..254}; do
  ping "${FILTERED_IP}.${HOST}" -c 1 -w 10 &>/dev/null &
done

for JOB in $(jobs -p); do wait "${JOB}"; done

ip neighbour | \
    awk 'tolower($0) ~ /reachable|stale|delay|probe/{printf ("%5s\t%s\n", $1, $5)}' | \
      sort --version-sort --unique
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top