menunggu jaringan dalam skrip bash

9

Saya menjalankan skrip yang bergantung pada jaringan yang sedang menyala dan berbagi jaringan dipasang. Script berjalan saat login (yang terjadi secara otomatis setelah boot). Masalahnya adalah pada saat skrip berjalan, saya biasanya belum memiliki alamat IP (DHCP). Saat ini saya hanya tidur skrip selama 15-an, tapi saya tidak suka pendekatan ini sama sekali, karena saya ingin dapat memberi tahu pengguna jika ada sesuatu yang salah.

Apa rencana saya, adalah loop sementara saya belum memiliki alamat IP dan melanjutkan ketika saya melakukannya. Yang terpenting, ia harus keluar setelah beberapa saat. Apa yang saya if [ ifconfig | grep "192.168.100" ];pikirkan adalah tetapi yang terjadi adalah grepconsume ];dan tidak menyukainya. Kemudian bash juga menjadi kesal, karena tidak dapat menemukan ];yang makan grep. Dan kemudian saya bahkan belum mengimplementasikan time-out.

Seseorang menyarankan untuk menjaga variabel, dan tidur untuk, katakanlah, satu detik di setiap iterasi dan tingkatkan variabel ini setiap kali. Berikut ini skrip lengkap saya (tidak berfungsi) (Saya cukup baru untuk bash scripting):

x=0
while [ ifconfig | grep "192.168.100." > /dev/null ]; do
    echo "no nework"
    if "$x" -gt 200; then
        #Time out here
        exit 1
    x=$((x+1))
    sleep .1
    fi
done

#continue with rest of script...

Setiap petunjuk ke arah yang benar akan sangat dihargai!

aguywithsocks
sumber
1
Jika init Anda adalah systemd, tulis file layanan yang menunggu network-online.target...
jasonwryan
tidak perlu mengarahkan grepoutput ke /dev/null. Gunakan -qopsi sebagai gantinya. Dan juga saya tidak mengerti jika ifconfig adalah ide yang bagus. Mengapa tidak menggunakan pingsaja?
buru
pingbisa gagal tergantung pada jaringan yang dimaksud. Lebih baik memeriksa konfigurasi sistem yang sedang berjalan.
Bratchley

Jawaban:

8

Sintaks shell

Anda tampaknya bingung tentang persyaratan dalam skrip shell. Setiap perintah shell memiliki status keluar, yang merupakan bilangan bulat antara 0 dan 255, dengan 0 berarti berhasil dan nilai lain yang berarti kegagalan. Pernyataan suka ifdan whileyang mengharapkan operan boolean memeriksa status keluar dari perintah dan memperlakukan 0 (sukses) sebagai benar dan nilai lainnya (kegagalan) sebagai salah.

Misalnya, grepperintah mengembalikan 0 jika pola ditemukan dan 1 jika pola tidak ditemukan. Begitu

while ifconfig | grep "192.168.100." > /dev/null; do 

mengulangi loop selama polanya 192.168.100.ditemukan dalam output dari ifconfig. Perhatikan bahwa polanya 192.168.100.cocok dengan string 192x168 1007, karena .dalam ekspresi reguler cocok dengan karakter apa pun; untuk mencari string literal, teruskan opsi -Fke grep. Untuk membalikkan kondisinya, letakkan !di depan.

while ! ifconfig | grep -F "192.168.100." > /dev/null; do 

Lebih jauh dalam skrip, Anda ingin membandingkan nilai variabel dengan angka. Anda menggunakan -gtoperator, yang merupakan bagian dari sintaks ekspresi kondisional yang dimengerti oleh testperintah. The testperintah kembali 0 jika ekspresi kondisional adalah benar dan 1 jika ekspresi kondisional adalah palsu.

if test "$x" -gt 200; then

Merupakan kebiasaan untuk menggunakan nama alternatif [untuk testperintah. Nama ini mengharapkan perintah diakhiri dengan parameter ]. Dua cara penulisan perintah ini persis sama.

if [ "$x" -gt 200 ]; then

Bash juga menawarkan cara ketiga untuk menulis perintah ini, dengan sintaks khusus [[ … ]]. Sintaks khusus ini dapat mendukung beberapa operator lebih banyak daripada [, karena [merupakan perintah biasa yang tunduk pada aturan parsing biasa, sementara [[ … ]]merupakan bagian dari sintaks shell.

Sekali lagi, perlu diingat bahwa [ini adalah untuk ekspresi kondisional , yang merupakan sintaksis dengan operator seperti -n,, -gt[tidak berarti “nilai boolean”: perintah apa pun memiliki nilai boolean (status keluar = 0?).

Mendeteksi bahwa jaringan sedang aktif

Cara Anda mendeteksi bahwa jaringan sedang tidak kuat. Khususnya, perhatikan bahwa skrip Anda akan dipicu segera setelah antarmuka jaringan apa pun memperoleh alamat IP dalam rentang yang ditentukan. Secara khusus, sangat mungkin bahwa DNS belum akan naik pada saat itu, apalagi jaringan berbagi dipasang.

Apakah Anda benar-benar perlu menjalankan perintah ini ketika seseorang masuk? Lebih mudah membuat perintah berjalan secara otomatis ketika jaringan dibesarkan. Cara melakukannya tergantung pada distribusi Anda dan apakah Anda menggunakan NetworkManager.

Jika Anda perlu menjalankan perintah ini sebagai bagian dari skrip login, maka uji untuk sumber yang benar-benar Anda butuhkan, bukan untuk keberadaan alamat IP. Misalnya, jika Anda ingin menguji apakah /net/somenode/somedirsudah terpasang, gunakan

while ! grep -q /net/somenode/somedir </proc/mounts; do
  sleep 1
done

Jika Anda memiliki pemula atau systemd ...

maka kamu bisa menggunakannya. Misalnya, dengan Pemula , tandai pekerjaan Anda sebagai start on net-device-up eth0(ganti eth0dengan nama antarmuka yang menyediakan konektivitas jaringan yang diinginkan). Dengan Systemd, lihat Menyebabkan skrip untuk dieksekusi setelah jaringan dimulai?

Gilles 'SANGAT berhenti menjadi jahat'
sumber
Saya kira /net/seharusnya begitu /proc/net?
sebix
@sebix Tidak, mengapa? Saya tidak berbicara tentang konfigurasi jaringan Linux. Saya memberikan contoh titik mount untuk sistem file jarak jauh, /netadalah lokasi umum untuk titik pemasangan tersebut.
Gilles 'SANGAT berhenti menjadi jahat'
Oke, jadi Anda memerlukan drive jaringan yang terpasang. Apakah ada solusi yang lebih umum?
sebix
@sebix Solusi untuk apa? Membutuhkan drive jaringan yang terpasang adalah contoh tujuan, bukan contoh solusi.
Gilles 'SANGAT berhenti menjadi jahat'
1

Hitung saja output dari ip add showMisalnya:

root@xxxxxxlp01 ~ $ ip add sh dev eth3 | grep inet
root@xxxxxxlp01 ~ $ ip add sh dev eth1 | grep inet
root@xxxxxxlp01 ~ $ ip add sh dev eth0 | grep inet
    inet xxx.xxx.64.91/24 brd xxx.xxx.95.255 scope global eth0
    inet6 fe80::224:e8ff:fe78:4dfb/64 scope link
root@xxxxxxlp01 ~ $ ip add sh dev eth0 | grep inet | wc -l
2

Maka Anda bisa saja bercabang pada jumlah garis yang dikembalikan sesuai kebutuhan. Anda mungkin baru saja memeriksa apakah itu nol, dan jika demikian, tidur dan ulangi loop.

Kode yang belum diuji untuk ilustrasi:

while [ 1 ]; do

  if [ $(ip add sh dev eth0 | grep inet | wc -l) -ne 0 ]; then
     break
  fi

  sleep 1

done
Bratchley
sumber
1

Ping akan mengembalikan respons 0 jika setidaknya satu upaya berhasil. Anda mungkin mempertimbangkan untuk melakukan ping ke server yang Anda hubungkan hingga berhasil.

brwtx
sumber