Пример сценария для проверки состояния ваших интерфейсов с помощью команды ping
с использованием параметра -I
, рекомендованного @Raman Sailopal в его комментарии:
for i in $( ls /sys/class/net )
do
ping -c1 -I $i 8.8.8.8 >> /dev/null 2>&1
if [ $? -eq 0 ]
then
echo Your $i interface is connected
else
echo Your $i interface is disconnected
fi
done
Некоторые проблемы:
O_NONBLOCK
влияет на описание открытого файла, а не только на дескриптор файла. Например, если вы запустите that-script; cat
, вы увидите cat: -: Resource temporarily unavailable
, так как cat
stdin стал неблокирующим -read()
возвращает ошибку EAGAIN, если в данный момент нет ввода и установлен eof. perl
eof()
вызывает read()
и подразумевает буферизованный ввод-вывод. Вы не можете использовать его для неблокирующего ввода-вывода -. В вашем примере первый block1
читается в eof()
, затем select()
ждет в течение sleep 1
, а второй block1
читается в read()
, который возвращает оба block1
с. Здесь вам лучше использовать блокирующий ввод-вывод и использовать alarm()
, например, для тайм-аута. Если вы используете неблокирующий ввод-вывод -и select()
, не используйте eof()
и используйте sysread()
вместо read()
и убедитесь, что вы сбросили флаг O_NONBLOCK
при выходе, если он был установлен заранее (по-прежнему плохая идея устанавливать O_NONBLOCK
на стандартный ввод, так как этот стандартный ввод может использоваться совместно с другими процессами ).
Следуя предложениям Стефана, я придумал это, и пока, кажется, оно работает.
#!/usr/bin/perl -w
use strict;
my $timeout = 2;
my $buf = "";
my $blocksize = 30;
my $readsize;
my $nread;
my $buflen;
my $alarm;
my $eof;
open(my $in, "<&", "STDIN") or die;
do {
eval {
local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
alarm $timeout;
# Add upto the next full block
$readsize = $blocksize - (length $buf) % $blocksize;
do {
$nread = sysread $in, $buf, $readsize, length $buf;
$readsize -= $nread;
} while($nread and $readsize);
alarm 0;
};
if ($@) {
die unless $@ eq "alarm\n"; # propagate unexpected errors
$alarm = 1;
} else {
$alarm = 0;
}
print "B:$buf<\n";
$buf = "";
$eof = not ($nread or $alarm);
} while(not $eof);