2009-11-10 5 views
7

Come si può distribuire script Perl nativi (non "compilati/perl2exe/...") senza forzare gli utenti a conoscere i moduli personalizzati (non CPAN) di cui gli script hanno bisogno per funzionare?Come distribuire gli script nativi perl senza un overhead del modulo personalizzato?

Il problema è che gli utenti copieranno inevitabilmente lo script da qualche altra parte nel sistema e rimuoveranno lo script dal suo ambiente nativo e quindi non potrà più trovare i moduli necessari per l'esecuzione.

A volte mi sono accontentato di copiare il modulo nello script vero e proprio, ma preferirei una soluzione più pulita.

Aggiornamento: è meglio chiarire. Distribuisco un gruppo di script che capita di utilizzare moduli simili nel back-end. Gli utenti capiscono come eseguire script Perl, ma piuttosto che fare affidamento su "non spostare lo script" preferisco semplicemente consentire loro di spostare i file. Il percorso di minor resistenza.

+1

I moduli sono privati ​​di uno specifico script o sono condivisi da più script? Il primo caso viene solitamente implementato posizionando i moduli in una cartella lib che risiede accanto al file * .pl. Il secondo implica l'installazione dei moduli su site/lib o su un'altra posizione in PERL5LIB. –

risposta

4

Se uno script preparato per un client richiede moduli "personalizzati", è sufficiente comprimere i moduli come se si stessero tentando di caricarli su cpan. Quindi consegnare il pacchetto al client e utilizzare l'utilità cpan per installare lo script e i moduli.

+0

Hmm ... forse. Ho letto il problema come "gli utenti finali spostano il file * .pl dopo l'installazione" (presumibilmente sotto falso presupposto che sia autonomo) piuttosto che come installare in primo luogo. –

+4

L'ho letto come "come installo i moduli che contengono uno script?". Il fatto che un pacchetto possa anche installare lo script stesso è solo un ulteriore vantaggio, IMHO. – innaM

+4

Sospetto che l'originale "installazione" sia costituita da "decomprimere questo file", senza che l'utente realizzi le dipendenze tra i file. Se l'installazione è più complessa, ad esempio invocando cpan o eseguendo uno script di installazione, allora la tentazione di spostare semplicemente i file .pl andrà via. Se è richiesto è irrilevante; la semplice * illusione * di un'installazione complicata sarà sufficiente per mantenere i file al loro posto. –

6

Il modo giusto è di dire "Non farlo!" Spero che non si aspettino di spostare un file exe e che il programma continui a funzionare. Questo non è diverso.

Detto questo, ci sono un paio di alternative. Uno sta sostituendo lo script con un wrapper (ad es. Pl2bat) che conosce il percorso completo dello script reale. Un altro è usare PAR, ma ciò richiederebbe l'installazione di PAR e/o parl (da PAR :: Packer).

+0

+1 Non c'è bisogno di downvotare questo. I requisiti dell'OP sono contraddittori. –

+0

Mi piacerebbe un commento su * perché * qualcuno l'ha trovato inutile. –

+0

Ho avuto problemi con entrambe le parti della risposta. Provenendo da un background IT generale, non ho trovato pratico aspettarsi che il comportamento degli utenti noti cambi per soddisfare un oscuro requisito tecnico. Inoltre, penso che un file exe senza un programma di installazione formale/dovrebbe/funzionare da qualsiasi punto del sistema.Se un programma ha dipendenze esterne, quelle dovrebbero essere installate correttamente, quindi quella posizione nel filesystem non ha importanza. –

2

Distribuire un programma di installazione insieme allo script. Il programma di installazione dovrà essere eseguito con i privilegi di root e inserirà i moduli personalizzati nella posizione di sistema standard (/ usr/local/lib/perl5/site_perl o qualsiasi altra cosa).

Non ho provato questo, ma Module::Install sembra utile in questo senso. E 'descritto come un:

autonomo, estensibile Perl modulo installatore

+0

L'installazione di moduli specifici dell'applicazione in posizioni di sistema è un ottimo modo per mettere a rischio le collisioni tra file e spazio dei nomi. –

+2

Suppongo che ci siano dei compromessi su tutto, ma un po 'di accortezza può ridurre il rischio che le collisioni nello spazio dei nomi siano praticamente nulle nel caso di un modulo Perl. L'autore potrebbe semplicemente creare uno spazio dei nomi di primo livello basato sul suo nome o nome della società ed è altamente probabile che sia unico. –

+0

Modulo :: Il programma di installazione in realtà non esegue nulla che non è possibile ottenere da Module :: Build o ExtUtils :: Makemaker. –

0

Sarebbe davvero bello se si potrebbe utilizzare un fascio NeXTSTEP style application. Dato che probabilmente non stai sviluppando per una piattaforma che usa i bundle, dovrai farlo.

Inserire tutti i file di supporto in una posizione nota e puntare il file eseguibile in tali file per accedere alle impostazioni e alle librerie. Il modo più semplice per farlo è con un semplice programma di installazione.

Ad esempio, con un'applicazione chiamata foo, mettere tutti i file necessari in /opt/xlyd_apps/foo, biblioteche /opt/xlyd_apps/foo/lib, configurazione /opt/xlyd_apps/foo/etc, e così via. Metti l'eseguibile in /opt/xlyd_apps/foo/bin.

La cosa importante è quello di assicurarsi l'eseguibile sa di dover cercare in /opt/xlyd_apps/foo per tutti i suoi chicche, per cui se il cliente/cliente spostare lo script foo in una nuova posizione l'installazione funziona ancora.

Quindi, anche se non è possibile rendere l'intero oggetto autonomo e ricollocabile, è possibile rendere rilocabile lo script di chiamata effettivo.

+0

Questo è semplicemente un hardcoding di un percorso di libreria nell'applicazione. Questo non sembra un ottimo approccio * a meno che * non sia una caratteristica della piattaforma. Forse aggiungere un passo di indirezione renderebbe le cose più salde. Metti i tuoi moduli personalizzati in una cartella/opt ... e installa solo un singolo modulo super-semplice nelle librerie di sistema che conoscono il percorso dei moduli personalizzati. In questo modo, non esegui i percorsi hardcode in più di un posto. – tsee

2

Come variante del "mettere i moduli in un unico luogo e rendere le applicazioni a conoscenza di esso", che funziona anche su più computer e reti, forse si dovrebbe verificare PAR::Repository rispettivamente PAR::Repository::Client. Dovresti solo fornire un singolo eseguibile del client binario che si connette al repository (tramite file system o https) ed esegue qualsiasi numero arbitrario di programmi (utilizzando un insieme arbitrario di moduli) fornito dal repository richiesto dall'utente.

Se ci sono molti utenti, questo ha anche un vantaggio per la manutenzione: basta aggiornare il software fornito dal repository e gli utenti inizieranno a utilizzare il codice aggiornato per il loro sistema al successivo avvio dei programmi.

+0

Non qualcosa del genere richiede che questi moduli siano installati nella loro installazione perl? O è qualcosa che è completamente autonomo? – dlamotte

+0

PAR :: Packer produce eseguibili binari completamente autonomi. Tuttavia, raggruppa tutte le dipendenze con l'applicazione. Pertanto, potrebbe essere indesiderato se si desidera condividere il codice tra più applicazioni. (PAR fornisce diversi modi per risolvere questo problema, ma sto esaurendo la lunghezza dei commenti.) Nello scenario del repository, spedisci semplicemente un singolo loader.exe che può recuperare applicazioni e dipendenze dal repository, se necessario. Vedi anche: http://steffen-mueller.net/talks/appdeployment/ – tsee

-3

In realtà ho trovato la mia soluzione e sono curioso di sapere che tipo di ricezione avrà.

Ho scritto uno script che legge uno script perl e cerca istruzioni "use/require". Dopo averli trovati controlla se il modulo fa parte della libreria standard (guarda il percorso del modulo per /perl5/\d+.\d+[\d.]+/) e poi riscrive la riga use/require in due modi diversi a seconda di utilizzo.

Se richiedono è trovato:

{ 
    ... inline the entire module here... 
} 

Se uso si trova:

BEGIN { 
    ... inline the entire module here... 
} 

Se uso ha importazioni, seguono immediatamente sopra con:

BEGIN { import Module ...imports seen... } 

Capisco che questo non funzioni con i moduli che usano XS, ma mi andava bene con questo. Per lo più ho bisogno di supportare solo moduli Perl puri.

+0

Dai un'occhiata a Module :: ScanDeps per la risoluzione delle dipendenze e Module :: CoreList per verificare se viene fornito con la libreria predefinita. – tsee

+0

Oltre al fatto che non usa i moduli CPAN per fare questo ... perché questo processo è negativo? Il nocciolo della risposta è che inline il testo del modulo nello script. Non mi hai dato una ragione per cui questo è male. – dlamotte

+0

@xyld: se funziona, va bene. Ma ci sono molti casi in cui non funziona (inclusi i moduli XS, ovviamente). Mentre non ricordo il modulo esatto che mi ha fatto inciampare quando sono andato su questa strada, credimi non è una soluzione robusta. Allora, in realtà ho scritto un codice moderatamente sofisticato per risolvere automaticamente vari problemi. Non l'ho mai finito e sono andato con quello che so per funzionare bene. Ti farò sapere quando incontrerò i miei tentativi. – tsee