Làm cách nào để phát hiện trạng thái kết nối vật lý của cáp / đầu nối mạng?


145

Trong môi trường Linux, tôi cần phát hiện trạng thái kết nối hoặc ngắt kết nối vật lý của đầu nối RJ45 với ổ cắm của nó. Tốt nhất chỉ sử dụng kịch bản BASH.

Các giải pháp sau đây đã được đề xuất trên các trang web khác KHÔNG hoạt động cho mục đích này:

  1. Sử dụng 'ifconfig' - vì cáp mạng có thể được kết nối nhưng mạng không được định cấu hình đúng hoặc hiện không hoạt động.
  2. Ping máy chủ - vì sản phẩm sẽ nằm trong mạng LAN sử dụng cấu hình mạng không xác định và máy chủ không xác định.

Không có trạng thái nào có thể được sử dụng trong hệ thống tệp / Proc (mọi thứ khác đều ở đó)?

Làm thế nào Linux có thể có phiên bản bong bóng Windows của riêng họ bật lên từ khay biểu tượng cho biết bạn vừa rút cáp mạng?


Kent Fredriclothar , cả hai câu trả lời của bạn đều đáp ứng nhu cầu của tôi ... cảm ơn rất nhiều! Cái nào tôi sẽ sử dụng ... Tôi vẫn không biết.

Tôi đoán tôi không thể đặt cả hai bạn xuống làm câu trả lời đúng? Và nó có thể công bằng cho bạn rằng tôi chọn một. Tôi đoán một đồng xu? Một lần nữa cám ơn!

Câu trả lời:


228

Bạn muốn xem xét các nút trong

/ sys / lớp / mạng /

Tôi đã thử nghiệm với tôi:

Dây cắm:

eth0/carrier:1
eth0/operstate:unknown

Loại bỏ dây:

eth0/carrier:0
eth0/operstate:down

Dây được cắm lại:

eth0/carrier:1
eth0/operstate:up

Side Trick: thu hoạch tất cả các thuộc tính cùng một lúc một cách dễ dàng:

grep "" eth0/* 

Điều này tạo thành một danh sách tốt đẹp của các key:valuecặp.


8
Lưu ý rằng như Marco nói bên dưới giao diện phải được bật lên (ngay cả khi không được định cấu hình) để truy vấn các giá trị này.
Jamie Kitson

11
grep "" eth0 / * thật thanh lịch và dễ dàng, cảm ơn! :) Với công tắc -s grep sẽ không phàn nàn về các thư mục.
Ray

2
Tôi thích :: grep -H . eth0/*Dòng emty whipe này và in tên mục nhập thuộc về từng dòng.
F. Hauri

Có thể bỏ qua các lỗi về thư mục từ grep với:grep -s "" eth0/*
mrtumnus

Lưu ý rằng giao diện phải được lên. Xem câu trả lời của Marco dưới đây. Trong hệ thống của tôi, eth0 không được đặt theo mặc định và chương trình của tôi tạo ngẫu nhiên một địa chỉ IP cho nó. Tôi nhận được lỗi "Đối số không hợp lệ" khi trích dẫn nhà cung cấp dịch vụ
VocoJax

84

Bạn có thể sử dụng ethtool :

$ sudo ethtool eth0
Settings for eth0:
    Supported ports: [ TP ]
    Supported link modes:   10baseT/Half 10baseT/Full
                            100baseT/Half 100baseT/Full
                            1000baseT/Full
    Supports auto-negotiation: Yes
    Advertised link modes:  10baseT/Half 10baseT/Full
                            100baseT/Half 100baseT/Full
                            1000baseT/Full
    Advertised auto-negotiation: Yes
    Speed: 1000Mb/s
    Duplex: Full
    Port: Twisted Pair
    PHYAD: 0
    Transceiver: internal
    Auto-negotiation: on
    Supports Wake-on: umbg
    Wake-on: g
    Current message level: 0x00000007 (7)
    Link detected: yes

Để chỉ nhận trạng thái Liên kết, bạn có thể sử dụng grep:

$ sudo ethtool eth0 | grep Link
    Link detected: yes

liên kết ip | grep BROADCAST | cắt -d ':' -f 2 | trong khi đọc i; làm vang $ i; ethtool $ i | Liên kết grep; xong
Bryan Hunt

3
Lưu ý rằng như Marco nói bên dưới giao diện phải được bật lên (ngay cả khi không được định cấu hình) để truy vấn các giá trị này.
Jamie Kitson

điều này thật tuyệt! Tôi đã có một cách để kiểm tra xem ethernet có khả dụng không, nếu ethernet được bật, nếu ethernet được kết nối nhưng không có cách nào để kiểm tra xem cáp thực tế đã được kết nối chưa. grep LinkPhải không. Cảm ơn bạn!!
ᴛʜᴇᴘᴀᴛᴇʟ

Không làm việc ở đây. Ubuntu 16.04 trên phần cứng HP. giao diện không được định cấu hình là "không có liên kết", ngay cả khi bị buộc phải upnêu.
0xF2

26

Sử dụng 'màn hình ip' để nhận các thay đổi trạng thái liên kết THỜI GIAN THỰC.


3
Trong trường hợp của tôi, đây là câu trả lời duy nhất hoạt động ... / sys / class / net / eth0 / Carrier vẫn hiển thị 1khi cáp của tôi bị ngắt kết nối trong khi ip monitorthực sự hiển thị một cái gì đó
Tim Tonomall

Một số mở rộng về phương pháp này có thể được cảm ơn, Peter. Một cái gì đó giống như bất kỳ ví dụ nào trả lời câu hỏi ban đầu về việc biết trạng thái cắm cáp.
Sopalajo de Arrierez

17

cat /sys/class/net/ethX cho đến nay là phương pháp dễ nhất.

Giao diện phải được mặc dù, nếu không bạn sẽ nhận được một lỗi đối số không hợp lệ.

Vì vậy, đầu tiên:

ifconfig ethX up

Sau đó:

cat /sys/class/net/ethX

4
Hãy thử "cat / sys / class / net / eth [n] / operstate" trong đó [n] là số thiết bị eth.
pmont

Điều này chỉ cho bạn biết nếu eth [n] không hoạt động, Nếu nó xuống, nó không cho bạn biết cáp có được kết nối hay không.
Brice

@Brice, thực sự, bạn muốn kiểm tra tệp ethX/carrierlà 1 nếu phát hiện 'nhà cung cấp dịch vụ', nghĩa là cáp được kết nối và mang dữ liệu ...
Alexis Wilke

Điều này làm việc với tôi bằng cách sử dụng các lệnh Process Runtime Exec để kiểm tra xem cáp có được kết nối trong Android không.
Arlyn

Hoặc, sau khi ifconfig ethX lên, ifconfig ethX và tìm RUNNING.
craig65535

8

Ở cấp độ thấp, những sự kiện này có thể được bắt gặp bằng cách sử dụng ổ cắm rtnetlink mà không cần bỏ phiếu. Lưu ý bên lề: nếu bạn sử dụng rtnetlink, bạn phải làm việc cùng với udev hoặc chương trình của bạn có thể bị lẫn lộn khi udev đổi tên giao diện mạng mới.

Vấn đề với việc thực hiện cấu hình mạng với các kịch bản shell là các kịch bản shell rất tệ cho việc xử lý sự kiện (chẳng hạn như cáp mạng được cắm vào và ra). Nếu bạn cần thứ gì đó mạnh mẽ hơn, hãy xem ngôn ngữ lập trình NCD của tôi , ngôn ngữ lập trình được thiết kế cho các cấu hình mạng.

Ví dụ: tập lệnh NCD đơn giản sẽ in "cáp vào" và "cáp ra" thành thiết bị xuất chuẩn (giả sử giao diện đã được bật lên):

process foo {
    # Wait for device to appear and be configured by udev.
    net.backend.waitdevice("eth0");
    # Wait for cable to be plugged in.
    net.backend.waitlink("eth0");
    # Print "cable in" when we reach this point, and "cable out"
    # when we regress.
    println("cable in");   # or pop_bubble("Network cable in.");
    rprintln("cable out"); # or rpop_bubble("Network cable out!");
                           # just joking, there's no pop_bubble() in NCD yet :)
}

(nội bộ, net.backend.waitlink()sử dụng rtnetlink và net.backend.waitdevice()sử dụng udev)

Ý tưởng của NCD là bạn sử dụng nó để cấu hình mạng, do đó, thông thường, các lệnh cấu hình sẽ nằm ở giữa, chẳng hạn như:

process foo {
    # Wait for device to appear and be configured by udev.
    net.backend.waitdevice("eth0");
    # Set device up.
    net.up("eth0");
    # Wait for cable to be plugged in.
    net.backend.waitlink("eth0");
    # Add IP address to device.
    net.ipv4.addr("eth0", "192.168.1.61", "24");
}

Phần quan trọng cần lưu ý là việc thực thi được phép hồi quy ; trong ví dụ thứ hai, ví dụ, nếu cáp được kéo ra, địa chỉ IP sẽ tự động bị xóa.


4

Có hai trình nền phát hiện các sự kiện này:

ifplugdnetplugd


Tôi sử dụng ifplugstatuscông cụ từ ifplugddaemon. Không cần đối số, chỉ cần gõ ifplugstatusvà bạn sẽ nhận được tất cả các NIC như đã cắm hoặc rút phích cắm.
Sopalajo de Arrierez

3

Hầu hết các bản phân phối Linux hiện đại đều sử dụng NetworkManager cho việc này. Bạn có thể sử dụng D-BUS để lắng nghe các sự kiện.

Nếu bạn muốn một công cụ dòng lệnh để kiểm tra trạng thái, bạn cũng có thể sử dụng mii-tool, với điều kiện là bạn có Ethernet.


3
mii-tool đã được áp dụng bởi ethtool. mii-tool không biết về các liên kết GigE.
JimB

Ngoài ra, hầu hết các máy chủ đều có bộ điều hợp được cấu hình thủ công, bị bỏ qua bởi NM.
JimB

1
mii-tooldường như là lệnh duy nhất có thể báo cáo về trạng thái liên kết khi giao diện không hoạt động.
donothings thành công

2

Tôi sử dụng lệnh này để kiểm tra một dây được kết nối:

cd /sys/class/net/
grep "" eth0/operstate

Nếu kết quả sẽ lên hoặc xuống. Đôi khi nó không rõ, sau đó bạn cần kiểm tra

eth0/carrier

Nó hiển thị 0 hoặc 1


2

Một số giới hạn và thủ thuật

  1. Tôi làm tất cả điều này như người dùng bình thường (không phải root )

  2. Lấy infos từ dmesg

    Sử dụng dmesglà một trong những điều đầu tiên cần làm để tìm hiểu tình trạng hiện tại của hệ thống:

    dmesg | sed '/eth.*Link is/h;${x;p};d'
    

    có thể trả lời như:

    [936536.904154] e1000e: eth0 NIC Link is Down
    

    hoặc là

    [936555.596870] e1000e: eth0 NIC Link is Up 100 Mbps Full Duplex, Flow Control: Rx/Tx
    

    tùy thuộc vào trạng thái, tin nhắn có thể thay đổi tùy thuộc vào phần cứng và trình điều khiển được sử dụng.

    Nota: điều này có thể bằng văn bản dmesg|grep eth.*Link.is|tail -n1nhưng tôi thích sử dụng sed.

    dmesg | sed '/eth.*Link is/h;${x;s/^.*Link is //;p};d'
    Up 100 Mbps Full Duplex, Flow Control: Rx/Tx
    
    dmesg | sed '/eth.*Link is/h;${x;s/^.*Link is //;p};d'
    Down
    
  3. Kiểm tra xung quanh /syshệ thống tập tin giả

    Đọc hoặc viết dưới đây /syscó thể phá vỡ hệ thống của bạn, đặc biệt nếu chạy bằng root ! Mày đã được cảnh báo ;-)

    Đây là một phương pháp tổng hợp, không phải là theo dõi sự kiện thực sự .

    cd /tmp
    grep -H . /sys/class/net/eth0/* 2>/dev/null >ethstate
    while ! read -t 1;do
        grep -H . /sys/class/net/eth0/* 2>/dev/null |
            diff -u ethstate - |
            tee >(patch -p0) |
            grep ^+
      done
    

    Có thể hiển thị một cái gì đó như (một khi bạn đã rút và cắm lại, tùy thuộc):

    +++ -   2016-11-18 14:18:29.577094838 +0100
    +/sys/class/net/eth0/carrier:0
    +/sys/class/net/eth0/carrier_changes:9
    +/sys/class/net/eth0/duplex:unknown
    +/sys/class/net/eth0/operstate:down
    +/sys/class/net/eth0/speed:-1
    +++ -   2016-11-18 14:18:48.771581903 +0100
    +/sys/class/net/eth0/carrier:1
    +/sys/class/net/eth0/carrier_changes:10
    +/sys/class/net/eth0/duplex:full
    +/sys/class/net/eth0/operstate:up
    +/sys/class/net/eth0/speed:100
    

    (Nhấn Enterđể thoát khỏi vòng lặp)

    Nota: Điều này đòi hỏi patchphải được cài đặt.

  4. Tốt thôi, chắc là đã có thứ gì đó về điều này ...

    Tùy thuộc vào Cài đặt Linux , bạn có thể thêm if-upif-downtập lệnh để có thể phản ứng với loại sự kiện này.

    Trên Debian dựa trên (như Ubuntu ), bạn có thể lưu trữ tập lệnh của mình vào

    /etc/network/if-down.d
    /etc/network/if-post-down.d
    /etc/network/if-pre-up.d
    /etc/network/if-up.d
    

    xem man interfacesđể biết thêm thông tin


Cảm ơn ý kiến ​​của bạn và đầu vào về vấn đề này. Mặc dù, bạn có nhận ra rằng đây là những tập lệnh 'tự động'. Ở điểm 2, khi bạn nói đầu ra ' hoặc ' một đầu ra khác hoặc khi bạn nói " tùy thuộc vào trạng thái, thông báo có thể thay đổi tùy thuộc vào phần cứng và trình điều khiển được sử dụng " ... đó là một vấn đề lớn thực sự. Đầu ra phải nhất quán hoặc tập lệnh sản xuất bắt đầu bị phá vỡ. Nhưng đó là thông tin tốt bất kể, cảm ơn bạn.
Jeach

@Jeach Đầu ra có thể khác nhau có nghĩa là: Bạn có thể sử dụng trình điều khiển khác hơne1000 và sự đồng đều có thể xảy ra vào thời điểm khác936555.596870 , nhưng bạn sẽ thấy NIC Link is.
F. Hauri

2

Bạn có thể sử dụng ifconfig.

# ifconfig eth0 up
# ifconfig eth0

Nếu mục nhập hiển thị CHẠY, giao diện được kết nối vật lý. Điều này sẽ được hiển thị bất kể giao diện được cấu hình.

Đây chỉ là một cách khác để có được thông tin trong /sys/class/net/eth0/operstate.


Bạn đã tiết kiệm giờ của tôi !!
ADITYA VALLURU

1

trên linux linux. (tôi không chắc chắn trên các bản phát hành khác) bạn có thể xem toán hạng. Nó hiển thị nếu được kết nối hoặc xuống nếu không hoạt động trên

/sys/class/net/(interface name here)/operstate
#you can also put watch 
watch -d -n -1 /sys/class/net/(interface name here)/operstate

1
tail -f /var/log/syslog | grep -E 'link (up|down)'

hoặc cho tôi nhanh hơn được:

tail -f /var/log/syslog | grep 'link \(up\|down\)'

Nó sẽ nghe tập tin syslog.

Kết quả (nếu ngắt kết nối và sau 4 giây kết nối lại):

Jan 31 13:21:09 user kernel: [19343.897157] r8169 0000:06:00.0 enp6s0: link down
Jan 31 13:21:13 user kernel: [19347.143506] r8169 0000:06:00.0 enp6s0: link up

1

Bằng cách nào đó nếu bạn muốn kiểm tra xem cáp ethernet có được cắm vào linux sau khi khen không: "ifconfig eth0 down". Tôi tìm một giải pháp: sử dụng công cụ ethtool.

#ethtool -t eth0
The test result is PASS
The test extra info:
Register test  (offline)         0
Eeprom test    (offline)         0
Interrupt test (offline)         0
Loopback test  (offline)         0
Link test   (on/offline)         0

nếu cáp được kết nối, kiểm tra liên kết là 0, nếu không là 1.


0

Tôi đã sử dụng thiết bị nâng cao OpenWRT của mình làm bộ lặp (có thêm khả năng lan truyền ảo và mạng không dây) và thấy rằng các giá trị / sys / class / net / eth0 và các giá trị opstate không đáng tin cậy. Tôi đã chơi xung quanh với /sys/group/net/eth0.1 và /sys/group/net/eth0.2 cũng như (ít nhất là với phát hiện của tôi) không có cách nào đáng tin cậy để phát hiện ra rằng có thứ gì đó được cắm vào và nói chuyện trên bất kỳ của các cổng ethernet. Tôi đã tìm ra một cách hơi thô thiển nhưng có vẻ đáng tin cậy để phát hiện nếu có bất cứ thứ gì đã được cắm vào kể từ trạng thái khởi động lại / poweron cuối cùng ít nhất (hoạt động chính xác như tôi cần trong trường hợp của tôi).

ifconfig eth0 | grep -o 'RX packets:[0-9]*' | grep -o '[0-9]*'

Bạn sẽ nhận được 0 nếu không có gì được cắm và một cái gì đó> 0 nếu mọi thứ đã được cắm (ngay cả khi đã được cắm và kể từ khi gỡ bỏ) kể từ chu kỳ bật hoặc khởi động lại lần cuối.

Hy vọng điều này sẽ giúp ai đó ra ít nhất!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.