-
Problem z Petla Perl
Witam mam problem z zapetleniem czesci kodu.:confused:
Mianowicie pisze skrypt startowy do linuxa w ktorym mamy do wyboru kilka opcji dotyczacych nadawania adresu IP badz z serwera DHCP lub wpisanego recznie.
Problem polega na tym ze jezeli ades IP bedzie wartoscia nieprawdziwa (za duzo cyfr, oktety powyzej 255 itp) program ma sie zatrzymac i powrocic do wpisania ponownie zle wpisanego adresu ip.
Ponizej zamieszczam czesc kodu ktora odpowiada za reczne wpisanie adresu oraz procedure sprawdzajaca prawdziwosc IP.
# Start manual conf dla eth0
if ($wybor eq 4)
{
while(1)
{
# Pobierz adres IP dla interfejsu
print "Podaj adres IP: ";
$adres_ip = <STDIN>;
chomp $adres_ip;
if ($adres_ip) {
check_ip_addr();
}
# Pobranie Maski Podsieci
print "Podaj maske podsieci: ";
my $maska_podsieci = <STDIN>;
chomp $maska_podsieci;
check_ip_addr();
# podaj adres Bramy
print "Podaj adres bramy: ";
my $brama = <STDIN>;
chomp $brama;
check_ip_addr();
# Pobierz adres serwera DNS
print "Podaj adres primary DNS: ";
my $dns_1 = <STDIN>;
check_ip_addr();
print "Podaj adres secondary DNS: ";
my $dns_2 = <STDIN>;
check_ip_addr();
my $konfig = `/sbin/ifconfig eth0 $adres_ip $maska_podsieci`;
my $bramka = `/sbin/route add default gw $brama`;
# Dopisz adresy DNS do /etc/resolv.conf
my $plik = "/etc/resolv.conf";
open FILE, ">$plik" or die "Otwarcie pliku '$plik' do zapisu nie powiodlo sie: $! ";
print FILE "nameserver $dns_1";
print FILE "nameserver $dns_2";
close FILE;
}
}
# Wyjscie bez przypisanego ip
if(($wybor eq "x") || ($wybor eq "X")) {
exit(0);
}
else {
print("Illegal option! Try again!\n\n");
}
}
sub check_ip_addr
{
if ($adres_ip =~ /^(\d\d?\d?)\.(\d\d?\d?)\.(\d\d?\d?)\.(\d\d?\d?)$/)
{
my @table = ($1, $2, $3, $4);
foreach $octect (@table)
{
if ($octect le 255)
{
last;
} else
{
print ("You write wrong IP ADDRESS\n");
}
}
}
else
{
print ("You write wrong IP ADDRESS\n");
}
}
pozdrawiam
-
goto
witam
sie za bardzo nie znam na perlu bo dopiero troszke sie "bawiłem"
ale wydaje sie mi ze jakbys obdarzył etykieta pentle i uzył instrukcji goto ETYKIETA to by sie wracało tam gdzie chcesz
lub do karzdego pobrania adresu, maski, bramy stworzył odzielną pentlę i po nieprawidłowej składni urzył do przerwania pępli "redo " po czym jak pamiętam pętla zostanie jeszcze raz wykonana
-
# lub do karzdego pobrania adresu, maski, bramy stworzył odzielną pentlę i po # nieprawidłowej składni urzył do przerwania pępli "redo " po czym jak pamiętam pętla # zostanie jeszcze raz wykonana
Nie dokladnie rozumiem o co ci chodzi w tym momencie zauwaz ze jezeli sie zrobisz pelte while(1) {
pobranie_adresu;
moja_procedura();
}
ona sie zapelta juz w nieskonczonosc nawet po podaniu instrukcji last w procedurze w momencie spelnienia warunku w foreach.
redo powoduje wykonanie ponownie tej petli co nie ma sensu poniewaz ona juz sie zapetla w nieskonczonosc, funkcja exit zas spowoduje przerwanie calego skryptu a nie jak oczekiwalem tylko tej petli.
Coz jestem poczatkujacy w temacie perla wiec moge sie bardzo mylic:)
-
moze po :
Kod:
my $plik = "/etc/resolv.conf";
open FILE, ">$plik" or die "Otwarcie pliku '$plik' do zapisu nie powiodlo sie: $! ";
print FILE "nameserver $dns_1";
print FILE "nameserver $dns_2";
close FILE;
dopisz: exit;
spowoduje to wyjscie ze skryptum wiec nie bedzie sie zapetlal niepotrzebnie.
niestety nie mam teraz mozliwosci sprawdzenia tego.. wiec moge sie myslic badz zle Cie zrozumialem
-
Nie chce ci psuc przyjemnosci z odkrywania perla, wiec ogranicze sie do krotkiej sugestii..
Zamiast while(1) moglbys uzyc petli
do {
pobierz adresik itd;
} while ( sprawdzanko() );
Zamiast while mozesz tez uzyc until w zaleznosci od tego jak wyglada sprawdzanko().
A jak chcesz miec juz bardzo fajnie to zastap fraze "You write wrong IP" czyms bardziej zrozumialym np:
"Ty dac dobry adres jeszcze raz bitte!!!"<-koniecznie trzy wykrzykniki :)
Powodzenia !!!
psck
-
Dzieki za pomoc cos pomysle nad tym bo juz mi czacha zaczela dymic ;)
Teraz pozostaje wymyslec reszte kodu....:D
-
Jezeli to ma pobierac docelowo z jakiegos pliku (skoro to lub czesc tego ma sie wykonywac gdzies z poziomu skryptow startowych), to proponuje glowna petle zrobic na foreach lub while($wiersz = <PLIK>). A moze zamiast "startowy" miales na mysli "konfiguracyjny".
Co do tego co podeslales, zeby nie wnikac w szczegoly to:
kod....
petla glowna {
petla wewn1 {
# moze byc i while 1, byle by po poprawnym otrzymaniu wartosci byl "wywolany" operator last ,
# mozna oczywiscie uzywac przy petlach etykiet, wtedy mozesz wyjsc z zagniezdzonych petli
# ogolnie co do sterownaia petla to sa 3 operatory: last, next, redo , ale to juz pewnie wiesz
}
petla wewn2 {
}
..itd
} # koniec glownej
..dalszy kod...
-
Dzieki chlopaki petla do { ....} while(); zalatwila sprawe skrypcik chula jak trzeba.
Co do ostatniego posta mialem na mysli skrypt startowy poniewaz odpala sie go podczas startu systemu i sluzy do wybrania opcji pobrania adresu w zaleznosc od potrzeb np.: dhcp dla ethernetu, dhcp dla wirless, reczne wprowadzenie osobno dla eth i wirless, tak ze gdy pojdziesz sobie do cafe nie musisz klepac kilku komend po kazdym wlaczeniu tylko dokonujesz wyboru opcji i bangala ;)
Pozdro dla wszystkich zaangazowanych w pomoc
-
Ja to zrobiłem tak i działa :)
#!/usr/bin/perl
#
sub check_ip_addr {
$adr_name = shift (@_);
GL: {
print $adr_name;
while ($adres_ip = <>) {
if ($adres_ip =~ (/^(\d\d?\d?)\.(\d\d?\d?)\.(\d\d?\d?)\.(\d\d?\d?)$/)) {
my @table = ($1, $2, $3, $4);
foreach $octet (@table) {
if ($octet le 255) {
return $adres_ip;
last GL;
}else{
print "Zly IP:\n";
redo GL;
}
}
}else{
print "Zly IP:\n";
redo GL;
}
}
}
}
$adres = check_ip_addr("Wpissz Adres IP:\n");
print "Twój adres ip: $adres";
$maska = check_ip_addr("Wpissz Maske:\n");
print "Twója Maska: $maska";
-
ups mały błąd się wkradł :D teraz powinno być w miare good
#!/usr/bin/perl
#
sub check_ip_addr {
$adr_name = shift (@_);
GL: {
print $adr_name;
while ($adres_ip = <>) {
if ($adres_ip =~ (/^(\d\d?\d?)\.(\d\d?\d?)\.(\d\d?\d?)\.(\d\d?\d?)$/)) {
my @table = ($1, $2, $3, $4);
foreach $octet (@table) {
if ($octet le 255) {
}else{
print "Zly IP:\n";
redo GL;
}
return $adres_ip;
last GL;
}
}else{
print "Zly IP:\n";
redo GL;
}
}
}
}
$adres = check_ip_addr("Wpissz Adres IP:\n");
print "Twój adres ip: $adres";
$maska = check_ip_addr("Wpissz Maske:\n");
print "Twója Maska: $maska";