İnternet bağlantısını kontrol etmek için Elisp kodu


13

Emacs'ı açtığımda, paket arşivlerimi internet bağlantısı üzerinden yenilemeyi içeren init dosyamı değerlendiriyor. Bir internet bağlantım olmadığında bu sorunludur, bu nedenle internet bağlantısı olmadan Emacs'ı başlatırken bu kodun yürütülmesini önlemem gerekir. Bu sorunu çözmek için, internet bağlantım olmadığında Emacs'ın paket yenileme kodunu yoksaymasının bir yolu olup olmadığını merak ediyorum?

İşte ilk birkaç satır init.el:

;; Requisites: Emacs >= 24
(require 'package)
(package-initialize)

;; PACKAGE MANAGEMENT
(add-to-list 'package-archives 
  '("melpa" . "http://melpa.milkbox.net/packages/") t)

(package-refresh-contents)       

Emacs dosyamı aşağıdaki gibi yüklemek için kod ekleyebileceğimi hayal ediyorum:

;; Requisites: Emacs >= 24
(when (connected-to-internet-p)   ; I need this predicate function
  (require 'package)
  (package-initialize)
  (add-to-list 'package-archives 
               '("melpa" . "http://melpa.milkbox.net/packages/") t)
  (package-refresh-contents))

(connected-to-internet)Bu sorunu çözmek için bir işlev veya benzer bir yaklaşım var mı?


2
Burada ilgili bir cevap var stackoverflow.com/a/21065704/3170376 .
İsim

2
Emacs'ı başlattığınızda neden paket arşivlerini yenilemek istiyorsunuz?
phils

@ İsim Bu daha fazla ilgili. O var (çalışır varsayarak) cevap.
Malabarba

1
Her başlangıçta paket-yenileme-içeriklerini çalıştırmamanızı şiddetle tavsiye ederim. Büyük olasılıkla yapılandırmanızı yeni bir makinede aşağı çekerken bir kez çalıştırmanız gerekecektir ve daha sonra aylarca tekrar ihtiyacınız olmayacak. Bir bağlantınız olduğunda bunu yapmak bu sorunun yanlış cevabıdır, asıl sorun, ihtiyacınız olmadığında hiç çalıştırmamanızdır.
Jordon Biondo

Yanıtlar:


7

Hala içeriği otomatik olarak yenilemek istiyorsanız, mümkün olduğunda aşağıdaki kod gibi bir şey yapabilirsiniz:

(defun can-retreive-packages ()
  (cl-loop for url in '("http://marmalade-repo.org/packages/"
                        "http://melpa.milkbox.net/packages/"
                        "http://elpa.gnu.org/packages/")
           do (condition-case e
                  (kill-buffer (url-retrieve-synchronously url))
                (error (cl-return)))
           finally (cl-return t)))

Birkaç notun verilmesi:

  1. Bu yavaştır ve normal olarak başlatırken yavaş olacaktır, bu yüzden manuel olarak yapmayı tercih ederim.
  2. Genel olarak internet bağlantısını test etmenin bir yolu yoktur. Belirli bir hizmete ancak denediğiniz bir süreden sonra bağlanamadığınızı keşfedebilirsiniz. Bu aynı zamanda bu kadar yavaş olmasının nedenlerinden biridir.
  3. Kod, soruna nasıl yaklaşılacağının bir örneğidir. (ignore-errors (package-refresh-contents))Başarılı olup olmadığını umursamazsanız kolayca yapabilirsiniz .

Bunu yapmanın doğru yolu bu. Herhangi bir zamanda, İnternet'in bazı bölümlerine erişilebilir ve bazıları erişilemez ve bununla başa çıkmanın doğru yolu bağlantıyı araştırmaktır.
jch

1
Bu aynı zamanda bir sürü büyük görünmeyen arabellek oluşturacak, en iyisi (kill-buffer (url-ret ...))
Jordon Biondo

@JordonBiondo tamam, puan alındı. Bunu düşünmedim.
wvxvw

6

Kabuk betiklerimden benimsediğim basit bir çözüm

(defun internet-up-p (&optional host)
    (= 0 (call-process "ping" nil nil nil "-c" "1" "-W" "1" 
                       (if host host "www.google.com"))))

Bunu *scratch*tamponda test edebilirsiniz :

(message (if (internet-up-p) "Up" "Down"))
"Up"

Bu çözümü en çok seviyorum çünkü basit, hızlı ve daha geniş internete olan bağlantıyı test ediyor.
miguelmorin

4

Deneyebileceğiniz bir şey fonksiyon network-interface-list. Bir ağ arabirimleri listesi ve IP adresleri döndürür.

Benim için, hem Ethernet'e hem de wifi'ye bağlandığımda bu geri dönüyor:

(("en5" .
  [10 151 0 63 0])
 ("en0" .
  [10 151 2 76 0])
 ("lo0" .
  [127 0 0 1 0]))

Ve wifi'yi kapattığımda en0kayboluyor:

(("en5" .
  [10 151 0 63 0])
 ("lo0" .
  [127 0 0 1 0]))

Bunu deneyin ve İnternet bağlantınız olmadığında ne elde ettiğinizi görün. Örneğin, paketleri yalnızca hazır olduğunda yenilemek için en0aşağıdakileri yapın:

(when (assoc "en0" (network-interface-list))
  (package-refresh-contents))

Bu ilginç bir işlev. Anladım (("eth0" . [10 72 153 234 0]) ("lo" . [127 0 0 1 0]))çünkü ethernet'e bağlıyım.
Kaushal Modi

3

Legoscia'nın cevabını genişletmek için:

(defun test-internet ()
  (remove-if (lambda (el)
                   (string-match-p "lo.*" (car el)))
                 (network-interface-list)))

Bu, etkin ağ bağlantılarının bir listesini döndürür ( lo.*bazı durumlarda geri döngü arabirimidir, lodiğerlerinde lo#.

Test geri dönerse non-nil, bir ağ bağlantısı (wifi / ethernet, aslında dış internete ulaştığının garantisi yoktur. Bunun için bir test olarak bir yere ping atmak zorunda kalacaksınız), eğer geri dönerse nilpaketi almanın bir yolu yoktur liste.


2

loopbackArabirimleri ve ayrıca VirtualBox ve Docker arabirimlerini hariç tutmak için aşağıdakileri kullanıyorum . Umarım faydalıdır.

(defun tzz-has-network ()
  (remove-if (lambda (i)
               (or (string-match-p "\\(vboxnet\\|docker\\).*" i)
                   (member 'loopback (nth 4 (network-interface-info i)))))
             (mapcar 'car (network-interface-list))))

2

DBus ve NetworkManager ile modern bir Linux sisteminde:

(defun nm-is-connected()
  (equal 70 (dbus-get-property
             :system "org.freedesktop.NetworkManager" "/org/freedesktop/NetworkManager"
             "org.freedesktop.NetworkManager" "State")))

1

Bence yanlış şekilde bakıyorsun. Paketlerinizi gerçekten otomatik olarak güncellemek istiyorsanız, başlangıçta senkronize etmeyin: bir tür boşta kalma zamanlayıcısından yapın. Örneğin

(run-with-idle-timer 10 nil
  (lambda ()
    (package-refresh-contents)
    ..etc..))
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.