Как определить физическое состояние подключения сетевого кабеля / разъема?
-
03-07-2019 - |
Вопрос
В среде Linux мне нужно определить физическое состояние подключения или отсоединения разъема RJ45 к его разъему.Предпочтительно использовать только BASH-скрипты.
Следующие решения, которые были предложены на других сайтах, НЕ работают для этой цели:
- Использование 'ifconfig' - поскольку сетевой кабель может быть подключен, но сеть неправильно настроена или в данный момент не работает.
- Выполнить пинг хоста - поскольку продукт будет находиться в локальной сети, используя неизвестную конфигурацию сети и неизвестные хосты.
Разве нет какого-то состояния, которое можно использовать в файловой системе / proc (все остальное есть там)?
Каким образом в мире Linux предполагается наличие собственной версии Windows bubble, которая появляется в трее значков, указывающих на то, что вы только что отсоединили сетевой кабель?
Кент Фредрик и lothar, оба ваших ответа удовлетворяют мою потребность...большое спасибо!Какой из них я буду использовать...Я до сих пор не знаю.
Полагаю, я не могу назвать вас обоих правильным ответом?И, вероятно, для вас будет справедливо, если я выберу что-то одно.Подбросить монетку, я полагаю?Еще раз спасибо!
Решение
Вы хотите посмотреть на узлы в
/sys/class/net/
Я экспериментировал со своим:
Подключенный провод:
eth0/carrier:1
eth0/operstate:unknown
Удаленная Проволока:
eth0/carrier:0
eth0/operstate:down
Провод снова подключен:
eth0/carrier:1
eth0/operstate:up
Побочный Трюк:получение всех свойств сразу простым способом:
grep "" eth0/*
Это формирует хороший список key:value
пары.
Другие советы
Вы можете использовать инструмент 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
Используйте "ip monitor", чтобы получать изменения состояния канала в режиме РЕАЛЬНОГО ВРЕМЕНИ.
cat /sys/class/net/ethX
это, безусловно, самый простой метод.
Однако интерфейс должен быть запущен, иначе вы получите ошибку недопустимого аргумента.
Итак, сначала:
ifconfig ethX up
Тогда:
cat /sys/class/net/ethX
На низком уровне эти события могут быть перехвачены с помощью ссылка на rtnetlink сокеты, без какого-либо опроса.Боковое примечание:если вы используете rtnetlink, вам придется работать вместе с udev, иначе ваша программа может запутаться, когда udev переименует новый сетевой интерфейс.
Проблема с выполнением сетевых конфигураций с помощью сценариев оболочки заключается в том, что сценарии оболочки ужасны для обработки событий (например, подключаемый и отключаемый сетевой кабель).Если вам нужно что-то более мощное, взгляните на мой Язык программирования NCD, язык программирования, предназначенный для сетевых конфигураций.
Например, простой скрипт NCD, который выведет "cable in" и "cable out" в стандартный вывод (при условии, что интерфейс уже запущен):
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-адрес будет автоматически удален.
Существует два демона, которые обнаруживают эти события:
ifplugd и сетевой подключаемый модуль
Большинство современных дистрибутивов Linux используют Сетевой менеджер для этого.Вы могли бы использовать D-BUS для прослушивания событий.
Если вам нужен инструмент командной строки для проверки состояния, вы также можете использовать mii-tool
, учитывая, что вы имеете в виду Ethernet.
Я использую эту команду, чтобы проверить, подключен ли провод:
cd /sys/class/net/
grep "" eth0/operstate
Будет ли результат выше или ниже.Иногда он показывает неизвестное, тогда вам нужно проверить
eth0/carrier
Он показывает 0 или 1
Некоторые уточнения и хитрости
Я делаю все это как обычный пользователь (не корень)
Получайте информацию из
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
в зависимости от состояния сообщение может отличаться в зависимости от используемого оборудования и драйверов.
Nota:это могло бы быть написано
dmesg|grep eth.*Link.is|tail -n1
но я предпочитаю использовать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
Тест вокруг
/sys
псевдофайловая системаЧтение или запись в разделе
/sys
это может привести к поломке вашей системы, особенно если работать как корень!Вы были предупреждены ;-)Это метод объединения, а не реальный отслеживание событий.
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
(Удар Войти для выхода из цикла)
Nota:Для этого требуется
patch
подлежащий установке.В общем, что-то в этом уже должно быть...
В зависимости от Установка Linux, вы могли бы добавить
if-up
иif-down
скрипты, позволяющие реагировать на события такого рода.Вкл . Debian основанный (как Убунту), вы могли бы хранить свои скрипты в
/etc/network/if-down.d /etc/network/if-post-down.d /etc/network/if-pre-up.d /etc/network/if-up.d
видишь
man interfaces
для получения дополнительной информации.
tail -f /var/log/syslog | grep -E 'link (up|down)'
или для меня быстрее заводится:
tail -f /var/log/syslog | grep 'link \(up\|down\)'
Он будет прослушивать файл системного журнала.
Результат (при отключении и повторном подключении через 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
в arch linux.(я не уверен в других дистрибутивах) вы можете просмотреть 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
Ты может используйте ifconfig.
# ifconfig eth0 up
# ifconfig eth0
Если запись показывает, что она ЗАПУЩЕНА, значит, интерфейс физически подключен.Это будет показано независимо от того, настроен ли интерфейс.
Это просто еще один способ получить информацию в /sys/class/net/eth0/operstate
.
Я использовал свое усовершенствованное устройство OpenWRT в качестве ретранслятора (которое добавляет возможности виртуального ethernet и беспроводной локальной сети) и обнаружил, что значения /sys /class /net / eth0 carrier и opstate были ненадежными.Я поиграл с /sys/ class /net / eth0.1 и / sys / class / net / eth0.2, а также с (по крайней мере, на мой взгляд) отсутствием надежного способа обнаружить, что что-то было физически подключено и разговаривало на любом из портов ethernet.Я нашел немного грубый, но, казалось бы, надежный способ определить, было ли что-либо подключено, по крайней мере, с момента последней перезагрузки / включения питания (что работало именно так, как мне было нужно в моем случае).
ifconfig eth0 | grep -o 'RX packets:[0-9]*' | grep -o '[0-9]*'
Вы получите 0, если ничего не было подключено, и что-то > 0, если что-либо было подключено (даже если оно было подключено и с тех пор удалено) с момента последнего цикла включения питания или перезагрузки.
Надеюсь, это хотя бы кому-нибудь поможет!