sistema - ¿Cómo puede mi script de Perl encontrar su módulo en el mismo directorio?
perl ejecutar comando del sistema (8)
Desde perlfaq8 , que responde "¿Cómo agrego un directorio a mi ruta de inclusión (@INC) en tiempo de ejecución?" . También hay varias otras respuestas para preguntas sobre este tema.
¿Cómo agrego un directorio a mi ruta de inclusión (@INC) en tiempo de ejecución?
Estas son las formas sugeridas de modificar su ruta de inclusión, incluidas las variables de entorno, los conmutadores en tiempo de ejecución y las sentencias en código:
la variable de entorno PERLLIB
$ export PERLLIB=/path/to/my/dir
$ perl program.pl
la variable de entorno PERL5LIB
$ export PERL5LIB=/path/to/my/dir
$ perl program.pl
el indicador de línea de comando perl -Idir
$ perl -I/path/to/my/dir program.pl
el uso lib pragma:
use lib "$ENV{HOME}/myown_perllib";
El último es particularmente útil porque conoce las arquitecturas dependientes de la máquina. El módulo pragmático lib.pm se incluyó por primera vez con la versión 5.002 de Perl.
Hace poco escribí un nuevo script de Perl para matar procesos en función del nombre del proceso / nombre de usuario y lo extendí usando Classes para poder reutilizar el código de proceso en otros programas. Mi diseño actual es -
/home/mutew/src/prod/pskill <-- Perl script
/home/mutew/src/prod/Process.pm <-- Package to handle process descriptions
Agregué ~ / src / prod en mi variable $ PATH para acceder al script desde cualquier lugar. Al ejecutar la secuencia de comandos desde cualquier directorio que no sea el residente, conduce a "No se puede localizar Process.pm en @INC" (lo que es comprensible dado que, aparte de los directorios compartidos en / usr, @INC incluye solo el directorio actual - ''.''). Una solución que he estado usando es la directiva de uso de lib como tal -
use lib ''/home/mutew/src/prod'';
pero este es un problema importante de portabilidad. ¿Alguna solución que también me permita exportar el script a otros sistemas sin y sin cambios?
EDITAR
- Elegí la respuesta ''depesz'' como la correcta debido a su simplicidad y uso del módulo central.
- Aunque la respuesta de Brian Foy sugiere otros métodos para lograr lo mismo (TMTOWTDI), su contribución en perlfaq8 hace que esta pregunta sea absolutamente redundante.
Eche un vistazo a Par::Packer . Crea un ejecutable con todas las dependencias del script incluidas. Hace la distribución fácil. También podría proporcionar a sus usuarios una versión de su módulo que pueda instalarse en sus sistemas. Vea Module::Starter para una forma fácil de compilar todos los archivos necesarios para hacer una distribución estándar de estilo CPAN.
El enfoque más simple es encontrar el módulo FindBin. Me gusta esto:
use FindBin;
use lib $FindBin::Bin;
En general, prefiero tener mis scripts provistos de tal manera que los programas estén en lo que sea / bin, y las bibliotecas estén en lo que sea / lib
En estas situaciones uso un enfoque un poco más complicado:
use Cwd qw(abs_path);
use FindBin;
use lib abs_path("$FindBin::Bin/../lib");
La llamada a abs_path consiste en hacer que @INC contenga lo que sea / lib, y no lo que sea / bin /../ lib, es solo un ligero cambio, pero facilita la lectura de los mensajes de error.
Para convertir enlaces relativos a absoluto y agregar a @INC, normalmente uso ex :: lib. Por supuesto, esto solo es útil si planea mantener idénticas las ubicaciones relativas de la secuencia de comandos y el módulo en todas las máquinas donde planea ejecutar la secuencia de comandos.
Puedes hacer que Perl se vea en cualquier directorio usando el indicador -I
. Aquí, -I
significa @INC
que es la matriz de rutas en las que perl busca módulos. Usando -I
agrega la ruta dada a la matriz @INC
para esta ejecución.
p.ej:
perl -I lib bin/script.pl
donde lib contiene los módulos que quiero usar.
Sé que esto funciona para Perl 5 . No estoy seguro acerca de otras versiones.
Solo mantenlo simple. No es necesario importar ninguna biblioteca; simplemente encuentre su directorio de trabajo actual:
use lib "$ENV{PWD}/relativ_path_own_perllib";
Para problemas similares, puede leer la variable de entorno que proporciona su información sobre dónde se encuentra, el directorio de inicio, las cosas del sistema operativo, etc., con solo una fila de código de programación en el shell-terminal, como:
perl -e ''map { print; print " : ". $ENV{$_}." /n/r"; } sort keys %ENV ''
No es necesario enlazar algunas bibliotecas; solo use %ENV-Hash
.
Tengo curiosidad por qué la solución simplista
use File::Basename;
use lib dirname (__FILE__);
use SomeModuleLocatedInTheSameDirectoryAsThisPerlScriptOrModule;
no surgió El módulo FindBin parece tener algunos problemas si el archivo no es el script de Perl principal ejecutable, sino simplemente un módulo Perl no ejecutable. Al menos así es como interpreto el comentario en la documentation . Realmente no lo probé.
Para tener otra ruta relacionada con la ubicación de este archivo Perl, haz algo como
use File::Basename;
use lib dirname (__FILE__) . "/MyModules";
FindBin :: libs encontrará todas sus bibliotecas ubicadas en lugares razonables en relación con la ruta desde la que se ejecuta el script.