2011-01-26 7 views
5

Busco una manera de obtener dos tipos de información:Perl - ¿Puedo obtener rutas relacionadas con dónde reside un script y desde dónde se ejecutó?

  • La ruta completa donde reside un guión que incluye su nombre de archivo
  • La ruta completa donde una secuencia de comandos se ejecuta desde

Sé que puede usar $0 para obtener el nombre del archivo, pero ¿hay otras variables reservadas que sean originales de Perl que me den lo que estoy buscando?

Prefiero no usar ningún módulo especial, pero si es el único, entonces que así sea.

+3

"prefiero no utilizar cualquiera de los módulos especiales" -- ¿por qué? Tenga en cuenta que también hay muchos módulos que vienen empaquetados con la distribución perl. – Ether

+0

@ether - por la misma razón que no me gusta el ketchup en hotdogs, supongo – CheeseConQueso

Respuesta

2

La variable de entorno PWD contiene el directorio de trabajo actual, que debería ser la ruta desde la que se ejecutó el script.

Puede derivar la ruta completa de la secuencia de comandos con $ENV{PWD} y $0

Editar: proporcionar código de ejemplo, ya que es difícil para algunos a creer que esto es posible:

Puede que no haya recogido todo los posibles casos, pero esto debe estar muy cerca:

use strict; 
use warnings; 

print "PWD: $ENV{PWD}\n"; 
print "\$0: $0\n"; 

my $bin = $0; 
my $bin_path; 

$bin =~ s#^\./##; # removing leading ./ (if any) 

# executed from working directory 
if ($bin !~ m#^/|\.\./#) { 
    $bin_path = "$ENV{PWD}/$bin"; 
} 
# executed with full path name 
elsif ($bin =~ m#^/#) { 
    $bin_path = $0; 
} 
# executed from relative path 
else { 
    my @bin_path = split m#/#, $bin; 
    my @full_path = split m#/#, $ENV{PWD}; 

    for (@bin_path) { 
    next if $_ eq "."; 
    ($_ eq "..") ? pop @full_path : push @full_path, $_; 
    } 
    $bin_path = join("/", @full_path); 
} 

print "Script Path: $bin_path\n"; 

la producción de pruebas de funcionamiento:

PWD: /tmp 
$0: ../home/cmatheson/test.pl 
Script Path: /home/cmatheson/test.pl 

PWD: /home/cam 
$0: ./test.pl 
Script Path: /home/cam/test.pl 

PWD: /usr/local 
$0: /home/cam/test.pl 
Script Path: /home/cam/test.pl 

PWD: /home/cam/Desktop/foo 
$0: ../../src/./git-1.7.3.2/../../test.pl 
Script Path: /home/cam/test.pl 
+0

oh, sí ... ni siquiera pensé en eso. Gracias. la única pregunta que tengo sobre eso es si cuando cron ejecuta el script, ¿seguirá funcionando? – CheeseConQueso

+4

'$ PWD' contiene el directorio de trabajo actual del script, no la ubicación del script. Por ejemplo, mi cwd podría ser '~' pero el script podría estar ubicado en '/ usr/bin'. – Ether

+2

@cam: Este _ responde_ responde la segunda parte de la pregunta, desde donde se ejecuta el script. Sin embargo, esto no se puede usar para encontrar la ruta a la ubicación del script. Eliminar la última oración – maxelost

3
use File::Spec; 

print File::Spec->rel2abs($0); 

imprime la ruta completa de la secuencia de comandos incluyendo el nombre de archivo que desee.

+0

thanks deck - léalo – CheeseConQueso

0

Puede utilizar el módulo principal Cwd para obtener el directorio desde el que se ejecuta la secuencia de comandos, y el módulo de núcleo File::Spec para encontrar toda la ruta a la secuencia:

#!perl 

use strict; 
use warnings; 
use Cwd; 
use File::Spec; 

my $dir = getcwd(); 
print "Dir: $dir\n"; 

print "Script: " . File::Spec->rel2abs($0) . "\n"; 
+0

'getcwd()' devuelve el directorio de trabajo actual del script, no la ubicación del script. Por ejemplo, mi cwd podría ser '~' pero el script podría estar ubicado en '/ usr/bin'. – Ether

+0

Tomé "La ruta completa de donde se ejecutó un script desde" para indicar "la ruta en la que estaba cuando ejecuté el script". – CanSpice

+0

tiene la papelera correcta, quiero saber la ruta en la que estaba cuando ejecuté el guión. Además, quiero saber dónde vive el guión en sí – CheeseConQueso

2

Esto está disponible con el incorporado en $ FindBin :: Bin variable (ver perldoc FindBin):

use FindBin; 
use File::Spec; 

print "the location of my script is: ", $FindBin::Bin, "\n"; 
print "the basename of my script is: ", $FindBin::Script, "\n"; 
print "the full path (symlinks resolved) of my script is: ", File::Spec->catfile($FindBin::RealBin, $FindBin::RealScript), "\n"; 
7

Usando FindBin y Cwd:

#!/usr/bin/env perl 

use strict; 
use warnings; 

use Cwd  (); 
use FindBin (); 
use File::Spec(); 

my $full_path = File::Spec->catfile($FindBin::Bin, $FindBin::Script); 
my $executed_from_path = Cwd::getcwd(); 

print <<OUTPUT; 
Full path to script: $full_path 
Executed from path: $executed_from_path 
OUTPUT 

Salida de ejemplo (script guardado como /tmp/test.pl):

[email protected]:/usr/share$ /tmp/test.pl 
Full path to script: /tmp/test.pl 
Executed from path: /usr/share 
1

Se preguntó acerca de cosas especiales Perl y nadie ha mencionado __FILE__. Compruebe perldata para él y más. Puedo utilizar este lenguaje a menudo cuando tengo un subárbol relacionado de archivos/scripts/Modules-

use Path::Class qw(file); 
use File::Spec; 

my $self_file = file(File::Spec->rel2abs(__FILE__)); 
print 
    " Full path: $self_file", $/, 
    "Parent dir: ", $self_file->parent, $/, 
    " Just name: ", $self_file->basename, $/; 
2

Para una solución que también se ocupa de los enlaces simbólicos,

use Cwd   qw(realpath); 
use File::Basename qw(dirname); 

# Look for modules in the same dir as the script. 
use lib dirname(realpath($0)); 
Cuestiones relacionadas