วิธีการตรวจสอบสถานะการเชื่อมต่อทางกายภาพของสายเคเบิล / ขั้วต่อเครือข่าย?


145

ในสภาพแวดล้อม Linux ฉันต้องตรวจสอบสถานะการเชื่อมต่อทางกายภาพหรือการเชื่อมต่อของขั้วต่อ RJ45 กับซ็อกเก็ต ควรใช้สคริปต์ BASH เท่านั้น

วิธีแก้ไขปัญหาต่อไปนี้ซึ่งได้รับการเสนอบนไซต์อื่นไม่ทำงานเพื่อจุดประสงค์นี้:

  1. ใช้ 'ifconfig' - เนื่องจากอาจมีการเชื่อมต่อสายเคเบิลเครือข่าย แต่เครือข่ายไม่ได้รับการกำหนดค่าอย่างเหมาะสมหรือไม่ได้อยู่ในปัจจุบัน
  2. Ping โฮสต์ - เนื่องจากผลิตภัณฑ์จะอยู่ใน LAN โดยใช้การกำหนดค่าเครือข่ายที่ไม่รู้จักและโฮสต์ที่ไม่รู้จัก

มีสถานะใดบ้างที่สามารถใช้ในระบบไฟล์ / proc (ทุกอย่างอยู่ในนั้น)?

โลก Linux ควรจะมีบับเบิล Windows ของตัวเองที่โผล่ขึ้นมาจากไอคอนถาดเพื่อระบุว่าคุณเพิ่งถอดสายเคเบิลเครือข่ายหรือไม่


Kent Fredricและlotharคำตอบของคุณทั้งสองตอบสนองความต้องการของฉัน ... ขอบคุณมาก! ฉันจะใช้อันไหน ... ฉันยังไม่รู้

ฉันเดาว่าฉันไม่สามารถทำให้คุณทั้งคู่เป็นคำตอบที่ถูกต้อง? และอาจยุติธรรมสำหรับคุณที่ฉันจะเลือกอย่างใดอย่างหนึ่ง พลิกเหรียญฉันเดา? ขอบคุณอีกครั้ง!

คำตอบ:


228

คุณต้องการดูโหนดใน

sys / / ระดับ / / สุทธิ

ฉันทดลองกับฉัน:

ลวดเสียบใน:

eth0/carrier:1
eth0/operstate:unknown

ลวดลบออก:

eth0/carrier:0
eth0/operstate:down

ลวดเสียบอีกครั้ง:

eth0/carrier:1
eth0/operstate:up

เคล็ดลับด้าน: เก็บเกี่ยวคุณสมบัติทั้งหมดในครั้งเดียวด้วยวิธีที่ง่าย:

grep "" eth0/* 

นี่เป็นรายการ key:valueคู่ที่ดี


8
โปรดทราบว่าตามที่มาร์โกพูดด้านล่างอินเทอร์เฟซจะต้องขึ้น (แม้ว่าจะไม่ได้กำหนดค่า) เพื่อสอบถามค่าเหล่านี้
Jamie Kitson

11
grep "" eth0 / * ช่างสง่างามและง่ายขอบคุณมาก! :) ด้วย -s grep สวิตช์จะไม่บ่นเกี่ยวกับไดเรกทอรี
เรย์

2
ฉันชอบ:: grep -H . eth0/*นี่บรรทัด emty whipe และชื่อรายการพิมพ์ด้วยเป็นของแต่ละบรรทัด
F. Hauri

ข้อผิดพลาดเกี่ยวกับไดเรกทอรีจาก grep สามารถถูกละเว้นด้วย:grep -s "" eth0/*
mrtumnus

โปรดทราบว่าจะต้องมีส่วนต่อประสาน ดูคำตอบของมาร์โกด้านล่าง ในระบบของฉัน eth0 ไม่ได้ถูกตั้งเป็นค่าเริ่มต้นและโปรแกรมของฉันจะสร้างที่อยู่ IP แบบสุ่ม ฉันได้รับข้อผิดพลาด "อาร์กิวเมนต์ไม่ถูกต้อง" จากการส่งผู้ให้บริการ
VocoJax

84

คุณสามารถใช้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

ในการรับสถานะลิงก์เท่านั้นคุณสามารถใช้ grep:

$ sudo ethtool eth0 | grep Link
    Link detected: yes

ลิงค์ไอพี BROADCAST | cut -d ':' -f 2 | ในขณะที่อ่านฉัน; ทำเสียงก้อง $ i; ethtool $ i | ลิงค์ grep; เสร็จสิ้น
Bryan Hunt

3
โปรดทราบว่าตามที่มาร์โกพูดด้านล่างอินเทอร์เฟซจะต้องขึ้น (แม้ว่าจะไม่ได้กำหนดค่า) เพื่อสอบถามค่าเหล่านี้
Jamie Kitson

นี่มันเจ๋งมาก! ฉันมีวิธีการตรวจสอบว่าอีเธอร์เน็ตมีให้บริการหรือไม่หากเปิดใช้งานอีเธอร์เน็ตหากอีเธอร์เน็ตเชื่อมต่ออยู่ แต่ไม่มีวิธีการตรวจสอบว่ามีการเชื่อมต่อสายเคเบิลจริงหรือไม่ grep Linkทำมัน. ขอบคุณ!!
ᴛʜᴇᴘᴀᴛᴇʟ

ไม่ได้ทำงานที่นี่ Ubuntu 16.04 บนฮาร์ดแวร์ HP อินเตอร์เฟสที่ไม่ได้กำหนดค่าคือ "ไม่มีลิงก์" แม้ว่าจะบังคับให้upระบุ
0xF2

26

ใช้ 'ip monitor' เพื่อรับการเปลี่ยนแปลงสถานะลิงก์เวลาจริง


3
ในกรณีของฉันนี่เป็นคำตอบเดียวที่ทำงานได้ ... / sys / class / net / eth0 / ผู้ให้บริการยังคงแสดง1เมื่อสายเคเบิลของฉันถูกตัดการเชื่อมต่อในขณะที่ip monitorแสดงให้เห็นบางสิ่งบางอย่างจริงๆ
Tim Tisdall

บางคนที่เพิ่มเติมเกี่ยวกับวิธีการนี้อาจจะขอบคุณ Peter บางอย่างเหมือนตัวอย่างที่ตอบคำถามเดิมเกี่ยวกับการรู้สถานะปลั๊กสายเคเบิล
Sopalajo de Arrierez

17

cat /sys/class/net/ethX เป็นวิธีที่ง่ายที่สุด

อินเทอร์เฟซจะต้องมีขึ้นมิฉะนั้นคุณจะได้รับข้อผิดพลาดข้อโต้แย้งที่ไม่ถูกต้อง

ดังนั้นก่อน:

ifconfig ethX up

แล้ว:

cat /sys/class/net/ethX

4
ลองใช้ "cat / sys / class / net / eth [n] / operstate" โดยที่ [n] คือหมายเลขอุปกรณ์ eth
pmont

สิ่งนี้จะบอกคุณว่า eth [n] เพิ่มขึ้นหรือไม่หากไม่ได้ระบุว่าเชื่อมต่อสายเคเบิลหรือไม่
Brice

@ ราคาแน่นอนคุณต้องการตรวจสอบไฟล์ethX/carrierซึ่งเป็น 1 หากตรวจพบ 'ผู้ให้บริการ' ซึ่งหมายความว่ามีการเชื่อมต่อสายเคเบิลและกำลังดำเนินการข้อมูล ...
Alexis Wilke

สิ่งนี้ใช้ได้กับฉันโดยใช้คำสั่ง Process Runtime Exec เพื่อตรวจสอบว่าสายเคเบิลเชื่อมต่อใน Android หรือไม่
Arlyn

หรือหลังจาก ifconfig ethX ขึ้นแล้ว ifconfig ethX และค้นหา RUNNING
craig65535

8

ในระดับต่ำเหตุการณ์เหล่านี้สามารถจับได้โดยใช้ซ็อกเก็ตrtnetlinkโดยไม่มีการสำรวจใด ๆ หมายเหตุด้านข้าง: หากคุณใช้ rtnetlink คุณจะต้องทำงานร่วมกับ udev หรือโปรแกรมของคุณอาจสับสนเมื่อ udev เปลี่ยนชื่ออินเตอร์เฟซเครือข่ายใหม่

ปัญหาในการทำการกำหนดค่าเครือข่ายกับเชลล์สคริปต์คือเชลล์สคริปต์นั้นแย่มากสำหรับการจัดการเหตุการณ์ (เช่นสายเคเบิลเครือข่ายที่เสียบเข้าและออก) หากคุณต้องการสิ่งที่มีประสิทธิภาพยิ่งขึ้นลองดูที่ภาษาการเขียนโปรแกรม NCDของฉันซึ่งเป็นภาษาการเขียนโปรแกรมที่ออกแบบมาสำหรับการกำหนดค่าเครือข่าย

ตัวอย่างเช่นสคริปต์ NCD แบบง่ายที่จะพิมพ์ "สายเคเบิลใน" และ "สายเคเบิลออก" เป็น stdout (สมมติว่าอินเตอร์เฟสมีอยู่แล้ว):

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 :)
}

(ภายในnet.backend.waitlink()ใช้ rtnetlink และnet.backend.waitdevice()ใช้ udev)

แนวคิดของ NCD คือคุณใช้มันเพื่อกำหนดค่าเครือข่ายเท่านั้นดังนั้นโดยปกติคำสั่งการกำหนดค่าจะมาระหว่างกันเช่น:

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");
}

ส่วนที่สำคัญที่จะต้องทราบว่าการดำเนินการได้รับอนุญาตให้ถอยหลัง ; ในตัวอย่างที่สองตัวอย่างเช่นหากดึงสายเคเบิลที่อยู่ IP จะถูกลบโดยอัตโนมัติ


4

มี daemons สองตัวที่ตรวจพบเหตุการณ์เหล่านี้:

ifplugdและnetplugd


ฉันใช้ifplugstatusเครื่องมือจากifplugdภูต ไม่จำเป็นต้องมีข้อโต้แย้งเพียงแค่พิมพ์ifplugstatusและคุณจะได้รับ NIC ทั้งหมดว่าเสียบหรือถอดปลั๊ก
Sopalajo de Arrierez

3

ลีนุกซ์รุ่นใหม่ส่วนใหญ่ใช้NetworkManagerสำหรับสิ่งนี้ คุณสามารถใช้ D-BUS เพื่อฟังเหตุการณ์

หากคุณต้องการเครื่องมือบรรทัดคำสั่งเพื่อตรวจสอบสถานะคุณยังสามารถใช้งานmii-toolได้เนื่องจากคุณมี Ethernet อยู่ในใจ


3
mii-tool ถูกแทนที่ด้วย ethtool mii-tool ไม่รู้จักลิงก์ GigE
JimB

นอกจากนี้เซิร์ฟเวอร์ส่วนใหญ่มีการกำหนดค่าอะแดปเตอร์ด้วยตนเองซึ่ง NM จะถูกละเว้น
JimB

1
mii-toolน่าจะเป็นคำสั่งเดียวที่สามารถรายงานสถานะลิงก์เมื่ออินเตอร์เฟสหยุดทำงาน
donothingsuccessfully

2

ฉันใช้คำสั่งนี้เพื่อตรวจสอบสายเชื่อมต่อ:

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

หากผลจะขึ้นหรือลง บางครั้งมันแสดงว่าไม่รู้จักคุณต้องตรวจสอบ

eth0/carrier

มันแสดงให้เห็น 0 หรือ 1


2

ความแม่นยำและกลอุบายบางอย่าง

  1. ฉันทำทั้งหมดนี้เป็นผู้ใช้ปกติ (ไม่ใช่รูท )

  2. คว้าข่าวสารจาก dmesg

    การใช้dmesgเป็นสิ่งแรกที่ต้องทำเพื่อสอบถามสถานะปัจจุบันของระบบ:

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

    สามารถตอบบางสิ่งเช่น:

    [936536.904154] e1000e: eth0 NIC Link is Down
    

    หรือ

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

    ข้อความอาจแตกต่างกันไปขึ้นอยู่กับฮาร์ดแวร์และไดรเวอร์ที่ใช้

    หมายเหตุ: นี้โดยอาจจะเขียนแต่ผมชอบใช้dmesg|grep eth.*Link.is|tail -n1sed

    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. ทดสอบ/sysระบบแฟ้มหลอก

    การอ่านหรือเขียนภายใต้/sysอาจทำให้ระบบของคุณเสียหายโดยเฉพาะอย่างยิ่งหากทำงานเป็นroot ! คุณได้รับคำเตือน ;-)

    นี้เป็นวิธีการร่วมกันไม่ได้จริงติดตามกิจกรรม

    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
    

    สามารถแสดงผลเหมือน (เมื่อคุณถอดปลั๊กและเสียบกลับขึ้นอยู่กับ):

    +++ -   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
    

    (กดEnterเพื่อออกจากลูป)

    หมายเหตุ: ต้องpatchมีการติดตั้ง

  4. ไม่เป็นไรต้องมีบางอย่างเกี่ยวกับสิ่งนี้ ...

    ขึ้นอยู่กับการติดตั้ง Linuxคุณสามารถเพิ่มif-upและif-downสคริปต์เพื่อให้สามารถตอบสนองต่อเหตุการณ์ประเภทนี้

    สำหรับDebian based (เช่นUbuntu ) คุณสามารถเก็บสคริปต์ของคุณไว้

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

    ดูman interfacesข่าวสารเพิ่มเติม


ขอบคุณสำหรับความคิดเห็นและการป้อนข้อมูลของคุณในเรื่องนี้ แม้ว่าคุณจะรู้ว่าสคริปต์เหล่านี้เป็น 'อัตโนมัติ' ในจุดที่ 2 เมื่อคุณพูดเอาท์พุท ' หรือ ' เอาท์พุทอื่นหรือเมื่อคุณพูดว่า " ขึ้นอยู่กับสถานะข้อความอาจแตกต่างกันไปขึ้นอยู่กับฮาร์ดแวร์และไดรเวอร์ที่ใช้ " ... นั่นเป็นปัญหาใหญ่จริง เอาต์พุตจะต้องสอดคล้องหรือสคริปต์การผลิตเริ่มต้นที่จะทำลาย แต่มันเป็นข้อมูลที่ดีโดยไม่ต้องขอบคุณ
Jeach

@Jeach ผลลัพธ์อาจแตกต่างกันไปหมายถึง: คุณสามารถใช้ไดรเวอร์อื่น ๆ ได้e1000และการชดเชยอาจเกิดขึ้นในเวลาอื่นมากกว่า936555.596870แต่คุณจะเห็นNIC Link isทุกอย่าง
F. Hauri

2

คุณสามารถใช้ ifconfig

# ifconfig eth0 up
# ifconfig eth0

หากรายการแสดง RUNNING อินเทอร์เฟซจะเชื่อมต่อทางกายภาพ สิ่งนี้จะปรากฏขึ้นไม่ว่าจะมีการกำหนดค่าอินเทอร์เฟซหรือไม่

/sys/class/net/eth0/operstateนี้เป็นเพียงวิธีการที่จะได้รับข้อมูลในอีก


คุณประหยัดเวลาของฉัน !!
ADITYA VALLURU

1

บน linux arch (ฉันไม่แน่ใจใน distros อื่น ๆ ) คุณสามารถดู operstate ซึ่งจะปรากฏขึ้นหากเชื่อมต่อหรือลงหากไม่เปิดใช้งาน operstate

/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)'

หรือสำหรับฉันที่เร็วขึ้นจะได้รับ:

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

มันจะฟังไฟล์ syslog

ผลลัพธ์ (หากยกเลิกการเชื่อมต่อและหลังจากเชื่อมต่ออีก 4 วินาที):

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

ยังไงก็เถอะถ้าคุณต้องการตรวจสอบว่าสายอีเธอร์เน็ตเสียบอยู่ในลินุกซ์หลังจากการยกย่อง: "ifconfig eth0 down" ฉันค้นหาวิธีแก้ปัญหา: ใช้เครื่องมือ 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

หากเชื่อมต่อสายเคเบิลแล้วการทดสอบการเชื่อมโยงคือ 0 มิฉะนั้นจะเป็น 1


0

ฉันใช้อุปกรณ์ที่ได้รับการปรับปรุง OpenWRT ของฉันเป็น repeater (ซึ่งเพิ่มความสามารถอีเทอร์เน็ตเสมือนและ LAN แบบไร้สาย) และพบว่าผู้ให้บริการ / sys / class / net / eth0 และค่าสถานะไม่น่าเชื่อถือ ฉันเล่นกับ /sys/class/net/eth0.1 และ /sys/class/net/eth0.2 เช่นกัน (อย่างน้อยกับการค้นพบของฉัน) ไม่มีวิธีที่เชื่อถือได้ในการตรวจสอบว่ามีบางสิ่งที่เสียบเข้ากับร่างกายและพูดคุยกับสิ่งใด ของพอร์ตอีเธอร์เน็ต ฉันคิดออกมาเล็กน้อย แต่ดูเหมือนว่าจะมีวิธีที่น่าเชื่อถือในการตรวจสอบว่ามีสิ่งใดเสียบอยู่ตั้งแต่สถานะรีบูต / poweron ล่าสุดอย่างน้อย (ซึ่งทำงานได้อย่างที่ฉันต้องการในกรณีของฉัน)

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

คุณจะได้รับ 0 หากไม่มีการเสียบปลั๊กและบางสิ่ง> 0 หากมีการเสียบปลั๊กใด ๆ (แม้ว่าจะเสียบปลั๊กและถอดออก) ตั้งแต่เปิดเครื่องครั้งสุดท้ายหรือรอบรีบูต

หวังว่านี่จะช่วยให้ใครบางคนออกมาอย่างน้อย!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.