インターネット接続を確認するためのElispコード


13

Emacsを開くと、initファイルが評価されます。これには、インターネット接続を介したパッケージアーカイブの更新が含まれます。これは、インターネットに接続していないときに問題になるため、インターネットに接続せずにEmacsを起動するときにそのコードの実行を防止する必要があります。この問題を解決するために、インターネットに接続していないときにEmacsがパッケージの更新コードを無視する方法があるのだろうか?

ここに私の最初の数行があります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ファイルをロードするコードを追加できると思います。

;; 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)この問題を解決する機能、または同様のアプローチはありますか?


2
関連する答えがここにありますstackoverflow.com/a/21065704/3170376
名前

2
Emacsの起動時にパッケージアーカイブを更新したいのはなぜですか?
phils

@Nameそれは関連しているだけではありません。それ答えです(動作すると仮定します)。
マラバルバ

1
各スタートアップでpackage-refresh-contentsを実行しないことを強くお勧めします。新しいマシンで最初に構成をプルダウンするときに一度実行する必要があり、その後数か月間は必要ありません。接続しているときにそれを行うことは、この問題に対する間違った答えです。本当の問題は、接続する必要がないときに実行していることです。
ジョードンビオンド

回答:


7

可能であれば、コンテンツを自動的に更新したい場合は、次のコードのようなことができます。

(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)))

いくつかの注意事項があります:

  1. これは遅く、通常の起動時には遅くなるので、私はむしろ手動で行います。
  2. 一般にインターネット接続をテストする方法はありません。特定のサービスに接続できなかったのは、ある程度の時間をかけてからだとわかります。これもまた、非常に遅い理由の1つです。
  3. コードは、問題へのアプローチ方法をより具体的に示しています。(ignore-errors (package-refresh-contents))成功したかどうかを気にしなければ簡単にできたはずです。

それは明らかにそれを行う正しい方法です。いつでも、インターネットの一部はアクセス可能ですが、一部はアクセスできないため、インターネットに対処する適切な方法は、接続をプローブすることです。
jch

1
これにより、大量の未表示のバッファーも作成されます。(kill-buffer(url-ret ...))
Jordon Biondo

@JordonBiondo OK、ポイントを取った。それについて考えていません。
wvxvw

6

シェルスクリプトから採用した簡単なソリューションは

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

これは*scratch*バッファでテストできます:

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

このソリューションは、シンプルで高速であり、より広いインターネットへの接続をテストするため、最も気に入っています。
ミゲルモリン

4

試すことができるのは、関数network-interface-listです。ネットワークインターフェイスとそのIPアドレスのリストを返します。

私にとって、これはイーサネットとWiFiの両方に接続したときに返されるものです:

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

そして、wifiをオフにするとen0消えます:

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

それを試して、インターネットに接続していないときに何が得られるかを確認してください。たとえば、en0起動時にのみパッケージを更新するには、次のようにします。

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

これは興味深い機能です。私は(("eth0" . [10 72 153 234 0]) ("lo" . [127 0 0 1 0]))イーサネットに接続しているので得ます。
カウシャルモディ

3

レゴシアの答えを拡大するには:

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

これは、(アクティブなネットワーク接続のリストを返しますlo.*いくつかのケースでは、ループバックインタフェースであるlo他でlo#

テストがを返す場合、non-nilネットワーク接続があります(wifi /イーサネット、実際には外部のインターネットに到達する保証はありません。テストのためにどこかにpingする必要があります)、戻る場合nil、パッケージを取得する方法はありませんリスト。


2

以下を使用して、loopbackインターフェイスとVirtualBoxおよびDockerインターフェイスも除外します。お役に立てば幸いです。

(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とNetworkManagerを備えた最新のLinuxシステムの場合:

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

1

あなたはそれを間違った方法で見ていると思います。パッケージを本当に自動更新する場合は、起動時に同期的に実行しないでください。何らかのアイドルタイマーから実行してください。例えば

(run-with-idle-timer 10 nil
  (lambda ()
    (package-refresh-contents)
    ..etc..))
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.