Newsgroup: it.comp.lang.perl
Titolo: Invocare uno script da perl

Salve,
ho uno script in perl ( 
dispatch.pl
 ) ceh funziona senza problemi.
Adesso avrei bisogno di invocare dall'interno di questo uno script (
setenv.sh ) che imposta delle variabili d'ambiente per 
dispatch.pl
; lo
script setenv.sh si trova una directory più sù ( insomma .. ), fatto così:
export DHLMODELSDIR="./aiprod/models";
export DHLSCRIPTSDIR="./scripts";
export DHLATTACHESDIR="./attaches";
export DHLOUTPUTDIR="./processedfiles";
Lo script lo richiamo da 
dispatch.pl
 così:
`../
setenv.pl
`;
Il sistema operativo su cui sto lavorando è HP UX 11, e vorrei sapere cosa
non funziona, inquanto quando lo script ( setenv.sh ) termina le variabili
non sono più presenti nel sistema. Me ne accorgo facendo, dal suo interno,
un
env | grep DHL
Grazie a tutti,
j0k3r
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it

 non sono più presenti nel sistema. Me ne accorgo facendo, dal suo interno,
E' una faq:
http://www.perl.it/documenti/faq/view.html?pag=8&faq=34
Di più non so.

 setenv.sh ) che imposta delle variabili d'ambiente per 
dispatch.pl
; 
la cosa è molto più complessa di quanto sembri. quando esegui un comando 
esterno in perl (ad es. con le backtick), stai lanciando in effetti un 
altro processo (in questo caso un'altra shell) che ha le *sue* variabili 
d'ambiente. quando il processo lanciato termina, si porta appresso nella 
tomba tutte le sue variabili. non è un bug, è proprio che è fatto così 
il funzionamento dei processi.
hai 2 modi per risolvere il problema:
1) se il tuo script è semplice e tutto quello che fa è impostare 
variabili, prova a leggerlo, parsarlo e impostare a mano le variabili. 
una cosa tipo:
   open(SH, "../setenv.sh");
   while(<SH>) {
     chomp;
     if(/^export (.*)="(.*)";$/) {
         $ENV{$1} = $2;
     }
   }
   close(SH);
questa soluzione è un po' deboluccia, in quanto potresti dover 
utilizzare nel tuo script cose come:
   export FOO=bar
   export FOOBAR=foo$FOO
e non funzionerebbe più nulla...
2) puoi usare uno "sporco trucco" che consiste nel fare una exec() verso 
il tuo script shell e poi ritornare allo script perl (in questo modo non 
viene instanziato alcun nuovo processo e le variabili d'ambiente 
rimangono intatte). ad esempio, il tuo "
dispatch.pl
" potrebbe essere 
fatto così:
   #!/usr/bin/perl
   exec(". ../setenv.sh && $0") unless $ENV{DHLMODELSDIR};
   # il resto dello script...
questo script usa la variabile DHLMODELSDIR come discriminante: se non è 
impostata, esegue lo script shell (nota che la notazione ". script" è 
obbligatoria, altrimenti non funziona) e poi ritorna allo script attuale 
($0), stavolta con la variabile impostata.
ci sono 2 prerequisiti: a) chmod +x sugli script e shebang impostate 
correttamente (e questo è abbastanza ovvio) e b) devi lanciare lo script 
come "./
dispatch.pl
" (non con la forma "perl 
dispatch.pl
") altrimenti 
non funziona[1].
cheers,
Aldo
[1] se proprio ti capita di dover lanciare lo script come "perl 
dispatch.pl
", puoi provare a sostituire la prima riga con:
   exec(". ../setenv.sh && $^X $0") unless $ENV{DHLMODELSDIR};
così *dovrebbe* (ma dipende in qualche misura dal sistema operativo, 
dalla shell e dalla versione del Perl) funzionare in entrambi i modi. YMMV.

 il funzionamento dei processi.
[ CUT ]
Grazie per la risposta, adesso vado a fare alcuni test.
Il problema però è un altro: se io eseguissi semplicemente 
set VAR = pippo
sarei anche d'accordo con te; il fatto che ho usato export per far sì che
esplicitamente le variabili siano impostate a livello di shell....ma
probabilmente sto facendo un errore di valutazione....
Comunque ti farò sapere....


 probabilmente sto facendo un errore di valutazione....
è indifferente. dal manuale di bash (notare la parte tra asterischi):
        The environment *inherited by any executed command* consists of
        the shell's initial environment, whose values may be modified in
        the shell, less any pairs removed by the unset command, plus any
        additions via the export and declare -x commands.
quando tu esegui il tuo script con i backtick, esegui una *nuova* shell, 
e in *quella* shell esegui l'export delle variabili. ogni processo 
lanciato da *quella* shell vedrà le variabili che hai impostato. fin qui 
tutto bene.
il problema è che al ritorno dai backtick, *quella* shell muore, e ti 
ritrovi con le variabili impostate dalla shell *di partenza*, in pratica 
nella condizione in cui eri *prima* di esportare le variabili.
se vuoi vederla in un altro modo, export non può funzionare 
all'indietro. definisce variabili nel processo corrente e le esporta 
verso i processi creati dal processo corrente. non esporta verso il 
processo che ha lanciato il processo corrente.
cheers,
Aldo