Controllo connessione in background: stranezze?

Salve a tutti ragazzi, vi sottopongo una “stranezza” che non riesco ancora a capire. Vi spiego prima cosa faccio.

Per alcune simulazioni atmosferiche scarico automaticamente alcuni dati da un opportuno server. Mi collego a internet e avvio il mio “scriptone” che mi fa tutto automaticamente (simulazione compresa+upload risultati). La funzione che controlla lo scarico dei dati si chiama “g2sub” (vedi più in basso). Fin qui tutto ok.

Ora, siccome la cosa deve avvenire anche in mia assenza ho pensato: perché non verificare (ed eventualmente ripristinare) anche la connessione a internet in automatico?
Così ho creato il seguente script, che fa il controllo ogni 5 minuti e che lancio in background (scusate, l’indentazione viene persa quando incollo qui…):

for (( cycle = 1; cycle <= 10000; cycle++ ))
do
while ! ping -q -w1 www.google.it
do
# se internet non va, ma la chiavetta è connessa
killall pppd
# riconnetti e aspetta
wvdial >& wvdial.log &
sleep 10
done
sleep 300
done

Questo script funziona e navigo tranquillamente. Ma lo script g2sub ora fa le bizze… inizia a scaricare ma poi si blocca. Sul terminale vedo quanto segue:
*
File to download: 17.

Check data available from g2sub Nomads server 1…
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 24636 0 24636 0 0 2298 0 --:–:-- 0:00:10 --:–:-- 3704

GFS Data download from Nomads server 1. File 1/17.
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 621k 0 621k 0 0 46672 0 --:–:-- 0:00:13 --:–:-- 60740

GFS Data download from Nomads server 1. File 2/17.
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 584k 0 584k 0 0 75 0 --:–:-- 2:11:26 --:–:-- 0
curl: (18) transfer closed with outstanding read data remaining

GFS Data download from Nomads server 1. File 2/17.
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 505k 0 505k 0 0 65 0 --:–:-- 2:11:21 --:–:-- 0
curl: (18) transfer closed with outstanding read data remaining …*

Cioè all’inizio tutto bene, poi non riesce a scaricare gli altri file (vi assicuro che nn è un problema del server da cui scarico: quando lo faccio senza lo script di controllo è tutto ok, sono 2 giorni che faccio le prove).

Che ci sia qualche impiccio con i processi in background?

Grazie a tutti e buon lavoro,
Fabio.

PS: in allegato la funzione g2sub (forse non elegantissima, ma testata per mesi e mi funziona perfettamente…).

g2sub()
{

step=1
stop=0
for (( count = 0; count <= stop; count++ ))
do
incr=00
fdate=date +%Y%m%d
checkcurl=1
checkdata1=1
checkday=50
waitnomads=1
STRINGTOSEND=“Stringtosend”
rm -f ${gfsdir}/check*
rm -f ${gfsdir}/run${run}/check*
MICROSUBREG=“subregion=&leftlon=0&rightlon=1&toplat=40&bottomlat=39”

echo
echo “File to download: $nfiles.”

while $checkdata1 -ne 0 -a printf "%02d" $checkday -ne date +%d -u ] && $waitnomads -ne 5 ]
do
STRINGTOCHECK1=“http://nomads.ncep.noaa.gov/cgi-bin/filter_gfs_hd.pl?file=gfs.tprintf "%02d" $runz.mastergrb2f24&$LEVSTRING$VARSTRING$MICROSUBREG&dir=%2Fgfs.$fdate$run%2Fmaster”
STRINGTOCHECK2=“http://nomad3.ncep.noaa.gov/cgi-bin/g2subset_gfs-0.5.pl?file=gfs.tprintf "%02d" $runz.pgrb2fprintf "%02d" $incr&$LEVSTRING$VARSTRING$MICROSUBREG&dir=”

for (( server1 = 1; server1 <= 5; server1++ )) 
do 
  if  $checkdata1 -ne 0 -o $checkcurl -ne 0 ] 
    then 
      echo 
      echo "Check data available from g2sub Nomads server 1..." 
      curl "$STRINGTOCHECK1" -o ${gfsdir}/checkdir1 
      checkcurl=$? 
      cd ${gfsdir} 
      checkdata1=`grep -c -i "NOT PRESENT" checkdir1` 
      checkgrep=$? 
      if  $checkgrep -eq 2 ] 
        then 
          checkdata1=1 
      fi 
      sleep 30 
    else 
      server1=5 
  fi 
done 

if  $checkdata1 -ne 0 ] 
  then 
    echo 
    echo "Server 1 problems. Check data update from g2sub Nomads server 2..." 
    curl "$STRINGTOCHECK2" -o ${gfsdir}/checkdir2 
    checkcurl=$? 
    # Check if server 2 data are today data... 
    cd /root/WPS/util 
    ./g2print.exe -v ${gfsdir}/checkdir2 >& ${gfsdir}/checkgrib2.txt 
    sed -n '20p' ${gfsdir}/checkgrib2.txt >& ${gfsdir}/checkgrib2row.txt 
    checkday=`cut -c64 ${gfsdir}/checkgrib2row.txt` 
    echo 
fi 

if $checkcurl -ne 0 ] || $checkdata1 -ne 0 -a printf "%02d" $checkday -ne date +%d -u ]
then
checkdata1=1
checkday=50
waitnomads=$(( $waitnomads + 1 ))
echo “Data not available yet, or network problems. Wait 3 minutes for run $run UTC again, $waitnomads/5…”
sleep 180
fi
done

for (( nfile = 1; nfile <= nfiles; nfile++ ))
do
if $checkdata1 -eq 0 ]
then
echo
echo “GFS Data download from Nomads server 1. File $nfile/$nfiles.”
STRINGTOSEND=“http://nomads.ncep.noaa.gov/cgi-bin/filter_gfs_hd.pl?file=gfs.tprintf "%02d" $runz.mastergrb2fprintf "%02d" $incr&$LEVSTRING$VARSTRING$SUBREG&dir=%2Fgfs.$fdate$run%2Fmaster”
else
if printf "%02d" $checkday -eq date +%d -u ]
then
echo
echo “GFS Data (rotating) download from Nomads server 2. File $nfile/$nfiles.”
STRINGTOSEND=“http://nomad3.ncep.noaa.gov/cgi-bin/g2subset_gfs-0.5.pl?file=gfs.tprintf "%02d" $runz.pgrb2fprintf "%02d" $incr&$LEVSTRING$VARSTRING$SUBREG&dir=”
fi
fi

# Send the string, get file and check if ok. 
curl "$STRINGTOSEND" -o /$rundir/gfs.t`printf "%02d" $run`z.master.grbf`printf "%02d" $incr` 
checkcurl=$? 
cp /$rundir/gfs.t`printf "%02d" $run`z.master.grbf`printf "%02d" $incr` /$rundir/checklastfile 
cd ${gfsdir}/run${run} 
checkdata=`grep -c -i "NOT PRESENT" checklastfile` 
checkgrep=$? 
if  $checkgrep -eq 2 ] 
  then 
    checkdata=1 
fi 

# Problem to download single file? Try again that file. 
if  $checkdata -ne 0 ] ||  $checkcurl -ne 0 ] 
  then 
    if  $checkgrep -ne 2 ] 
      then 
        sleep 1 
        nfile=$(( $nfile - 1 )) 
        incr=$(( $incr - $runstep )) 
        step=$(( $step + 1 )) 
          if  $step -eq 10 ] 
            then 
              stop=1 
          fi 
      else 
        stop=1 
    fi 
  else 
    # Everything seems OK. So keep a copy of data. 
    cd ${rundir} 
    /bin/tar -czf $dir_arc/${rundate}_gfs_05.tar.gz gfs.t${run}z.master* 
    stop=0 
fi 
wait 
incr=$(( $incr + $runstep )) 
done 

done

Final function check. If not ok, it will be run ftp2m function to try retrieve data.

if $checkdata1 -eq 0 -o printf "%02d" $checkday -eq date +%d -u ] && $checkcurl -eq 0 -a $checkdata -eq 0 ]
then
echo
echo “Success!!!”
check=0
else
echo
echo “Problems with Nomads G2SUB servers. Try FTP2ME…”
check=1
fi

return $check
}

Chiedo scusa in anticipo: non ho controllato il codice.
Ti consiglio di usare cron e crontab per automatizzare questi processi, senza la necessità di avviare in background un demone da te creato:
http://www.pluto.it/files/ildp/guide/lame/using-cron.html

Ti dovrebbe semplificare la vita ciao

Grazie della risposta “MarioS”!

Conosco cron e crontab, ma ho bisogno di automatizzare nel modo descritto, perché c’è tutta una sequenza di operazioni automatiche (ma non necessariamente cronologicamente fisse) che devo seguire.

In particolare l’obiettivo finale è quello di verificare (ed eventualmente ripristinare) la connessione, poco prima che serva davvero. E quando serve la connessione non lo posso prevedere perché dipende da altri fattori abbastanza “random”, diciamo.

Ho già provato a usare la verifica della connessione solo quando serve, ma ho lo stesso il problema che mi si “impazzisce” lo scarico dei dati, anche se la connessione è ripristinata e navigo tranquillamente.

Con crontab puoi eseguire lo script di controllo ogni 5 minuti senza usare i vari spleep che hai messo.
Scusa tu vuoi mettere tutto su file di log? Perchè hai scritto così?

 wvdial >& wvdial.log & 

Io avrei messo:

 wvdial > wvdial.log & 

Poi non ho capito, pretendi di lanciare uno script in backgroud che non occupi la sessione di bash ma che allo stesso tempo invii gli output sulla sessione non occupata?

domanda 1:
$gfsdir cos’è? non è dichiarata

$gfsdir è dichiarata nel resto dello script (sono più di 1500 righe…)
Quello che ho postato è solo la funzione che scarica i dati.

E’ vero che con crontab posso eseguire lo script di controllo ogni 5 minuti o altri intervalli, ma questo dei 5 minuti era solo x provare. In realtà il controllo mi serve solo quando necessario, ad esempio un attimo prima di scaricare i dati (poi se non ti connetti, ritenta) o quando mi serve di fare un upload. Non lo voglio dunque a intervalli di tempo regolari (tra ognuno dei quali poi il controllo verrebbe a mancare).

Quanto al file di log posso anche fare come dici tu (e l’ho fatto).

Sul background: il mio script principale su cui lavoro non è in background. In background ci deve andare solo la parte che riguarda il controllo (wvdial compreso).

se vuoi mandami un PM, ci accordiamo e mi invii l’intero codice: appena ho una mezzoretta libera lo verifico.
Altrimenti non credo si possa fare molto

Alberto

Dunque crei uno script a parte e poi lo richiami normalmente nello script principale come se fossi da shell…
Non capisco dove sta il problema…

Concordo con quanto detto da futhar…anche se per il “bene comune” sarebbe interessante vedere le righe di codice interessate che danno problemi.
A me non inviare niente che non ho tempo e forse mi potrei sbagliare con qualche sintassi.

Ciao

Grazie MarioS, grazie Alberto.

Purtroppo l’intero codice non lo posso inviare in quanto è un lavoro che sto facendo per terzi…
In ogni caso non serve perché il resto del codice viene dopo. Ciò che è coinvolto nel problema è solo la funzione g2sub. Quindi non vi preoccupate di variabili apparentemente non definite o altro. Lo script intero, insieme con la g2sub funziona perfettamente. La differenza sta solo se la connessione la stabilisco io manualmente oppure no. Tutto qui.

Se la connessione la faccio stabilire automaticamente dallo script (inserendo naturalmente quella parte di codice che io ho invece postato a parte), allora mi si inchiodano i download.
Se invece faccio io (o tramite configurazione di rete con il pulsante attiva, oppure tramite wvdial in un terminale a parte) allora tutto ok.

capisco, comunque più tardi dò un’occhiata lo stesso al codice anche se capisci benissimo che per molte cose devo lavorare di immaginazione, e non sempre si ha fortuna, se non si ha tutti gli elementi sotto mano.

Alberto

Certo Alberto, avere una visione di insieme è sempre meglio. Ma come dicevo, tutto il codice che non ho postato non ha alcun rapporto con la parte che si occupa di internet.

In ogni caso grazie per il vostro preziosissimo supporto (e sopporto! ;-))

Fabio.

premetto: come avevo anticipato, NON posso darti la soluzione, per i motivi prima esposti. Ma ti dico quello che mi passa per la testa:
il problema è ovviamente relativo alle righe 72-91, dove costruisci il ciclo sugli $nfile/$nfiles. Qui sarebbe importante fare il debug di $incr, $run, $rundir, proprio nel loop, che a causa del curl incompleto, entra in stallo.
Il nodo quindi (ma va?) è proprio il perché di questo non-completamento dopo il primo file. Da quello che ho “visto”, posso solo dire che gli elementi in gioco sono questi, e io li debuggerei passo-passo. Ma non posso sapere il contesto di chiamata della routine e quindi mi fermo qui.
Come ti dicevo prima, posso fare ipotesi, e darti qualche spunto: oltre a concentrarti su quelle var,puoi provare a verificare come si comporta wget, visto che di curl (riga 89) qui usi solo lo switch -o, riproducibile tranquillamente in wget.

Le tue osservazioni meritano senz’altro di essere prese in considerazione e proverò quindi a sbatterci un po’ la testa. Nel frattempo però ho fatto altre prove posso illustrarti i seguenti “scenari”:

Scenario n.1

  • apro un terminale e mi connetto a internet con wvdial
  • apro un altro terminale e avvio il mio script come ho sempre fatto (cioè quello che uso da mesi e senza il controllo della connessione).
    Risultato: funziona tutto.

Scenario n.2

  • inserisco all’inizio del mio script detto sopra le seguenti righe
    *while ! ping -q -w1 www.google.it
    do
    killall pppd
    wvdial &
    done *
    cioè faccio avviare wvdial direttamente dal mio script, prima di ogni altra istruzione.
  • a connessione avvenuta quindi lo script prosegue con le solite istruzioni (= a quelli dello scenario 1)
    Risultato: mi si blocca il download.

Quindi la mia domanda è: perché il problema si verifica solo se avvio la connessione a internet richiamando wvdial dallo script mentre se effettuo la connessione manualmente va tutto bene? Lo script è lo stesso!

[quote]
Scenario n.2 -
inserisco all’inizio del mio script detto sopra le seguenti righe
while ! ping -q -w1 www.google.it
do
killall pppd wvdial &
done
cioè faccio avviare wvdial direttamente dal mio script, prima di ogni altra istruzione.[/quote]

scusami ma che senso ha un while di questo genere ? è un loop di una sola iterazione … per controllare la connessione non sarebbe meglio un “check” tipo
PROC=“processo da controllare”
PSCHECK=$(ps axu | grep $PROC | grep -v grep)
while :; do
if $PSCHECK ]; then
#codice nel caso sia tutto ok"
sleep tot_secondi
else
#codice per tirare su il processo
sleep tot_secondi
fi
done

ecco, io farei una cosa del genere, magari con controlli più granulari, magari come funzione da far girare in parallelo allo script.

e/o in fase di curl del contenuto, aggiungerei un controllo dello “stato” della connessione (io metto controlli sempre e comunque), in modo tale che per quei secondi di acquisizione dati siamo sicuri che non ci siano problemi di connessione

Mah, io lo trovo molto semplice:
“Finché la connessione non funziona, tenta di ripristinarla, altrimenti non fare nulla ed esci”. E’ proprio quello che mi serve. E di per sé funziona benissimo, anche se mi rendo conto che il tuo sistema magari è sicuramente migliore. Fa un’iterazione sola ma solo se la connessione va a buon fine alla prima “botta”. Ma non è sempre così! Spesso poi mi capita con la chiavetta hrg che si stabilisce la connessione, ma poi non naviga… allora un re-ping fa comodo, ecco il perché del while. Sennò mi bastava un if…

Ma il problema non è questo. Non è la “logica” di come stabilire la connessione. Il problema è che quando la connessione viene avviata “dall’interno” del mio script più “grande” allora mi si blocca la parte che poi esegue il download.
Se invece faccio la stessa cosa ma prima stabilisco la connessione manualmente tramite wvdial &, e poi avvio il mio script “grande”, allora il download è ok.

E’ questo che vorrei capire. Il motivo di questo strano comportamento. Che gli cambia alla parte che fa il download se la connessione la stabilisco io o tramite un comando da script? Anche perché facendo quei controlli granulari che dici tu va benissimo, purché wvdial non mi dia questi problemi!

Preferivo un controllo “al momento”, ma se non va allora opterò per lo script parallelo che va per conto suo (se uso 2 terminali, uno per lo script, uno per il controllo allora è tutto ok…

[quote] Ma il problema non è questo.
Se invece faccio la stessa cosa ma prima stabilisco la connessione manualmente tramite wvdial &, e poi avvio il mio script “grande”, allora il download è ok.
[/quote]
questo lo abbiamo capito :slight_smile:

io sto solo cercando di farti capire che quando non si ha idea di cosa succede in una parte del codice, quello che hanno insegnato a me è di mettere, razionalizzando il tutto, quanti più controlli possibile. e dato che mi pare di capire che il problema sia legato alla connessione, ti spingevo a mettere dei controlli sullo stato della stessa, anche dove pensi che non ci siano problemi.
In bocca al lupo :wink:

Alberto

Io concordo pienamente con futhar e mi piace molto quanto ha detto:

Sono d’accordo con voi, ma citazioni a parte:
non è un problema di “pensare di sapere”. Il mio script non ha problemi, nel senso che una volta stabilita la connessione non fallisce mai. Questo è un fatto.

Se invece il comando wvdial (DA SOLO: lasciamo perdere cicli while e simili) lo eseguo dall’interno dello script piuttosto che “manualmente”, mi dà problemi.

Davvero pensate che dipenda dal resto del codice che quando mi connetto a mano invece funziona? Mah… Ragazzi: una riga di codice in più solamente, questa:
wvdial &.
E il resto dello script invariato!

vabbe’ non mi va di fare polemica eh! :slight_smile:
ognuno segue la propria logica nelle cose che fa, e io rimango delle mie opinioni, e tu delle tue … amen!

piuttosto, non mi hai risposto alla domanda relativa a wget, provato a sostituirlo a cURL* in quel loop di cui parlavamo? roba da tre secondi, io proverei almeno per curiosità …
non devi passare particolari parametri, al massimo il -O per passargli il file che vuoi avere in locale:
wget -O FILE URL

… facci sapere

*)per la cronaca curl riporta questo errore:
A file transfer was shorter or larger than expected. This happens when the server
first reports an expected transfer size, and then delivers data that doesn’t match the
previously given size.
Apparentemente questo non spiega nulla, e stando così le cose si può quantomeno dire che è un comportamento anomalo, non spiegabile nè documentato (per quanto mi risulta, ma se qualcuno ha notizie a riguardo è ben accetto)