Этот ответ является результатом рассуждений, основанных на различных фактах, которые я нашел. Я не знаю, как работает реализация ядра Linux, поскольку я не являюсь разработчиком ядра и, похоже, существует изрядное количество бессмысленной дезинформации. Я предполагаю, что ядро Linux делает разумный выбор. Мой ответ должен применяться, если я не ошибаюсь.
Многие приводы используют коды ECC (коды исправления ошибок) для обнаружения ошибок чтения. Если данные повреждены, ядро должно получить URE (неустранимая ошибка чтения) для этого блока от диска с поддержкой ECC. В этих обстоятельствах (и есть исключение ниже) копирование поврежденных или пустых данных поверх хороших данных было бы безумием.В этой ситуации ядро должно знать, какие данные являются хорошими, а какие - плохими. Согласно это 2010 год, а RAID5 все еще работает… статья:
Рассмотрим эту альтернативу, которую, как мне известно, используют по крайней мере несколько производителей массивов.Когда диск в томе RAID сообщает URE, контроллер массива увеличивает счетчик и удовлетворяет ввод-вывод, перестраивая блок по четности. Затем он выполняет перезапись на диске, который сообщил URE (возможно, с проверкой), и если сектор плохой, микрокод будет переназначен, и все будет хорошо.
Однако теперь за исключением: если диск не поддерживает ECC, диск врет о повреждении данных или микропрограммное обеспечение особенно не работает, то URE может не передаваться, а поврежденные данные будут переданы ядру. В случае несоответствия данных: кажется, что если вы используете 2-дисковый RAID1 или RAID5, тогда ядро не может знать, какие данные верны, даже в не ухудшенном состоянии, потому что есть только одна четность блок, и не было зарегистрировано URE. В трехдисковом RAID1 или RAID6 один поврежденный блок без флага URE не будет соответствовать избыточной четности (в сочетании с другими связанными блоками), поэтому должно быть возможно надлежащее автоматическое восстановление.
Мораль этой истории такова: используйте диски с ECC. К сожалению, не все диски, поддерживающие ECC, рекламируют эту функцию. С другой стороны, будьте осторожны: я знаю кого-то, кто использовал дешевые SSD в двухдисковом RAID1 (или в RAID10 с двумя копиями). Один из дисков возвращал случайные поврежденные данные при каждом чтении определенного сектора. Поврежденные данные были автоматически скопированы поверх правильных данных. Если SSD использовал ECC и работал правильно, то ядро должно было предпринять надлежащие корректирующие действия.
При написании сценария вы можете запустить telnet в фоновом режиме, а затем, если он все еще работает после задержки, вы можете его убить. Пример:
{ printf "HEAD /\n\n"; sleep 1; } | telnet hostname port & sleep 2 && kill %1 2>/dev/null && echo "timeout"
Это ждет 2 секунды, прежде чем отключить фоновый telnet.
Телнет обязательно запускать? Я думаю, что timeout(1) поможет вам.
Вариант №1: Используйте тайм-аут, который является частью GNU coreutils. Это не подтвердит, удалось ли вам установить соединение или нет.
TIMEOUT=10 timeout $TIMEOUT telnet
Альтернатива #2: Используйте Bash/Perl/Python для решения той же проблемы с большей или меньшей степенью детализации.
Несколько примеров:
Bash: TIMEOUT=10; telnet
Perl : perl -e "alarm 10; exec @ARGV" "telnet my.server.com 23"
Python: python -c 'import telnetlib;HOST ="my.server.com"; ПОРТ=23; ТАЙМ-АУТ=10; ШАБЛОН="Логин: "; t = telnetlib.Telnet (ХОСТ, ПОРТ); t_read = t.read_until (ШАБЛОН, ТАЙМ-АУТ); print(repr(t_read))'
Это будет работать не более 2 секунд:
[]# echo quit | timeout --signal=9 2 telnet [SERVER] [PORT]