2011-01-26 2 views
5

Je cherche un moyen d'obtenir deux informations:Perl - Puis-je obtenir des chemins liés à l'endroit où un script réside et où il a été exécuté?

  • Le chemin complet de l'endroit où un script réside, y compris son nom de fichier
  • Le chemin complet où un script a été exécuté à partir

Je sais que vous pouvez utiliser $0 pour obtenir le nom du fichier, mais y a-t-il d'autres variables réservées qui sont propres à Perl et qui me donneront ce que je recherche?

Je préfère ne pas utiliser de modules spéciaux, mais si c'est le seul moyen, alors qu'il en soit ainsi.

+3

« Je préfère ne pas utiliser des modules spéciaux » -- Pourquoi? Notez qu'il y a beaucoup de modules qui sont fournis avec la distribution perl, aussi. – Ether

+0

@ether - pour la même raison que je n'aime pas ketchup sur les hot-dogs je suppose – CheeseConQueso

Répondre

2

La variable d'environnement PWD contient le répertoire de travail en cours, qui doit correspondre au chemin d'exécution du script.

Vous pouvez déduire le chemin complet du script avec $ENV{PWD} et $0

Modifier: fournir un exemple de code, car il est difficile pour certains à croire que cela est possible:

Je ne peux pas avoir pris tous les cas possibles, mais cela devrait être très proche:

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"; 

sortie de test est exécuté:

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 ouais .... je n'ai même pas pensé à ça. Merci. La seule question que je me pose à ce sujet est de savoir si quand cron lance le script, cela fonctionnera-t-il encore? – CheeseConQueso

+4

'$ PWD' contient le répertoire de travail actuel du script, pas l'emplacement du script. Par exemple, mon cwd pourrait être '~' mais le script pourrait être situé dans '/ usr/bin'. – Ether

+2

@cam: Ceci _doit_ répondre à la deuxième partie de la question - d'où le script est exécuté. Cependant, ceci ne peut pas être utilisé pour trouver le chemin vers l'emplacement du script. Enlevez la dernière phrase. – maxelost

3
use File::Spec; 

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

affiche le chemin d'accès complet à votre script, y compris le nom de fichier comme vous le souhaitez.

+0

merci deck - ill check it out – CheeseConQueso

0

Vous pouvez utiliser le module de base Cwd pour obtenir le répertoire à partir duquel le script a été exécuté, et le module noyau File::Spec pour trouver tout le chemin vers le script:

#!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()' renvoie le répertoire de travail actuel du script, pas l'emplacement du script. Par exemple, mon cwd pourrait être '~' mais le script pourrait être situé dans '/ usr/bin'. – Ether

+0

J'ai pris "Le chemin complet d'où un script a été exécuté à partir de" signifier "le chemin où j'étais quand j'ai exécuté le script". – CanSpice

+0

vous êtes correct canspice, je veux savoir le chemin où j'étais quand j'ai exécuté le script. en plus, je veux savoir où vit le script lui-même – CheeseConQueso

2

Il est disponible avec le intégré dans la variable $ FindBin :: Bin (voir 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

en utilisant FindBin et 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 

sortie de l'échantillon (script enregistré comme /tmp/test.pl):

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

Vous avez demandé des choses Perl spécial et personne n'a mentionné __FILE__. Vérifiez perldata pour cela et plus encore. J'utiliser cet idiome souvent quand j'ai une sous-arborescence des fichiers/connexes 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

Pour une solution qui gère également des liens symboliques,

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

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