GNU/Linux >> Belajar Linux >  >> Linux

Bagaimana saya bisa menulis skrip bash Linux yang memberi tahu saya komputer mana yang AKTIF di LAN saya?

Saya sarankan menggunakan flag 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

Yang mengatakan, jika Anda ingin menulisnya sendiri (yang cukup adil), inilah cara saya melakukannya:

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

..dan penjelasan dari setiap bit dari perintah di atas:

Membuat daftar alamat IP

Anda dapat menggunakan {1..10} sintaks untuk menghasilkan daftar angka, misalnya..

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

(ini juga berguna untuk hal-hal seperti mkdir {dir1,dir2}/{sub1,sub2} - yang menghasilkan dir1 dan dir2 , masing-masing berisi sub1 dan sub2 )

Jadi, untuk menghasilkan daftar IP, kami akan melakukan sesuatu seperti

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

Loop

Untuk mengulangi sesuatu di bash, Anda menggunakan for :

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

Ping

Selanjutnya, untuk ping.. Perintah ping sedikit berbeda dengan sistem operasi yang berbeda, distribusi/versi yang berbeda (saat ini saya menggunakan OS X)

Secara default (sekali lagi, pada versi OS X ping ) itu akan melakukan ping sampai terputus, yang tidak akan berfungsi untuk ini, jadi ping -c 1 hanya akan mencoba mengirim satu paket, yang seharusnya cukup untuk menentukan apakah mesin sedang aktif.

Masalah lainnya adalah nilai batas waktu, yang tampaknya 11 detik pada versi ping ini.. Diubah menggunakan -t bendera. Satu detik seharusnya cukup untuk melihat apakah mesin di jaringan lokal hidup atau tidak.

Jadi, perintah ping yang akan kita gunakan adalah..

$ 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

Memeriksa hasil ping

Selanjutnya, kita perlu tahu apakah mesin menjawab atau tidak..

Kita bisa menggunakan && operator untuk menjalankan perintah jika yang pertama berhasil, misalnya:

$ echo && echo "It works"

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

Bagus, jadi kita bisa melakukannya..

ping -c 1 -t 1 192.168.1.1 &&echo "192.168.1.1 sudah habis!"

Cara lain adalah dengan menggunakan kode keluar dari ping.. Perintah ping akan keluar dengan kode keluar 0 (sukses) jika berhasil, dan kode bukan nol jika gagal. Di bash Anda mendapatkan kode keluar perintah terakhir dengan variabel $?

Jadi, untuk memeriksa apakah perintah berhasil, kami akan melakukannya..

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

Menyembunyikan keluaran ping

Hal terakhir, kita tidak perlu melihat output ping, jadi kita bisa redirect stdout ke /dev/null dengan > pengalihan, misalnya:

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

Dan untuk redirect stderr (untuk membuang ping: sendto: Host is down pesan), Anda menggunakan 2> - misalnya:

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

Skrip

Jadi, untuk menggabungkan semua itu..

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

Atau, menggunakan && metode, dalam satu baris:

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

Masalah

Lambat .. Setiap perintah ping membutuhkan waktu sekitar 1 detik (karena kami menyetel -t batas waktu tanda ke 1 detik). Itu hanya dapat menjalankan satu perintah ping pada satu waktu.. Cara yang jelas untuk mengatasi ini adalah dengan menggunakan utas, sehingga Anda dapat menjalankan perintah bersamaan, tetapi itu di luar apa yang seharusnya Anda gunakan untuk bash..

"Thread Python - contoh pertama" menjelaskan cara menggunakan modul threading Python untuk menulis ping'er multi-utas.. Meskipun pada saat itu, saya akan sekali lagi menyarankan menggunakan nmap -sn ..


Di dunia nyata, Anda bisa menggunakan nmap untuk mendapatkan apa yang Anda inginkan.

nmap -sn 10.1.1.1-255

Ini akan melakukan ping ke semua alamat dalam rentang 10.1.1.1 hingga 10.1.1.255 dan memberi tahu Anda mana yang menjawab.

Tentu saja, jika Anda benar-benar ingin melakukan ini sebagai latihan bash, Anda dapat menjalankan ping untuk setiap alamat dan mengurai hasilnya, tetapi itu cerita lain.


Dengan asumsi jaringan saya 10.10.0.0/24, jika saya menjalankan ping di alamat siaran seperti

ping -b 10.10.0.255

Saya akan mendapat jawaban dari semua komputer di jaringan ini yang tidak memblokir port ping ICMP mereka.

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 

Jadi Anda hanya perlu mengekstrak kolom ke-4, dengan awk misalnya:

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:

Nah, Anda akan mendapatkan duplikat, dan Anda mungkin perlu menghapus ':'.

EDIT dari komentar :opsi -c membatasi jumlah ping karena skrip akan berakhir, kami juga dapat membatasi diri pada IP unik

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

Linux
  1. Cara Menggunakan Kata Sandi Terenkripsi di Linux Bash Shell Script

  2. Bagaimana menjalankan perintah bash Linux dalam skrip PERL?

  3. Cara Menemukan Shell Yang Anda Gunakan di Linux

  1. Bagaimana saya bisa memeriksa apakah PostgreSQL diinstal atau tidak melalui skrip Linux?

  2. Bagaimana saya bisa tahu di Linux proses mana yang mengirim sinyal ke proses saya

  3. Bagaimana saya bisa menguji skrip Bash saya pada versi Bash yang lebih lama?

  1. Bagaimana Mengetahui Distribusi Linux Yang Anda Gunakan?

  2. Bagaimana saya bisa menyelesaikan nama host ke alamat IP dalam skrip Bash?

  3. Bagaimana saya bisa mengidentifikasi proses mana yang membuat lalu lintas UDP di Linux?