2016-12-23 7 views
7

Wielu moich kolegów używa następujących poleceń w swoim bloku BEGIN.Zmiana na katalog, a następnie getcwd()

$scriptDir = dirname($0); 
chdir($scriptDir); 
$scriptDir = getcwd(); 

Mam rozejrzał się i nie może pomóc, ale myślę, że trzecia linia tj $scriptDir = getcwd(); jest zbędny. Ponieważ mamy już skryptdir od $scriptDir = dirname($0);. Czy coś tu brakuje?

+0

Jak pokazano poniżej, 'użyj FindBin qw ($ RealBin);' i nie zmieniaj katalogu. Pliki wymienione w '@ ARGV' odnoszą się do' pwd', a nie '$ RealBin'. – shawnhcorey

Odpowiedz

7

dirname($0) nie zwraca pełną ścieżkę, jak Chankey Pathak i Matthias wykazać.

Chciałbym dodać, że istnieją inne sposoby. Na przykład, można użyć FindBin (również rdzeń)

use FindBin qw($RealBin); 

BEGIN: { 
    my ($scriptDir) = $RealBin; 
    chdir $scriptDir    or die "Can't change to $scriptDir: $!"; 
}; 

The $RealBin daje takie samo jak to, co można pokazać, chyba że jest to pełna ścieżka z łączami rozwiązany.

chdir może zawieść, dzięki ikegami za komentarz. W takim przypadku zwracana jest wartość false, a powyższy kod umiera, należy odpowiednio dostosować. Zauważ, że kwestionowana trzecia linia nie ma z tym nic wspólnego.

Moduł ten jest również powszechnie wykorzystywane do względnej ścieżki do bibliotek z lib Pragma, na przykład

use lib "$RealBin/../lib"; 

co być może sprawia, że ​​nawet łatwiejsze decyzji wykorzystania go dla obu stron.


Co więcej, biorąc pod uwagę opis dirname z File::Basename (podkreślenie nie moja)

Funkcja ta jest udostępniona dla zgodności z poleceniem Unix shell dirname(1) i odziedziczył niektóre ze swoich dziwactw.Pomimo swojej nazwy zawsze zwraca nazwę katalogu, jak można się spodziewać. Aby być bezpiecznym, jeśli chcesz mieć nazwę katalogu ścieżki, użyj fileparse().

wolałbym iść nawet z

use Cwd qw(abs_path); 

BEGIN: { 
    my ($scriptDir) = abs_path(__FILE__) =~ m|(.*)/|; 
    chdir $scriptDir    
     or die "Can't change to $scriptDir: $!"; 
}; 

gdzie abs_path jest używany od __FILE__ na własną rękę nie może zapewnić pełną ścieżkę. Regex łapczywie łapie wszystko aż do ostatniej, /, czyli pełnej ścieżki do katalogu skryptu.

4
  • getcwd - Zwraca bieżący katalog roboczy
  • chdir - Zmienia katalog roboczy na wyrażenie

Poniżej przykład wyjaśnia to dobrze.

#!/usr/bin/perl 
use strict; 
use warnings; 
use File::Basename; 
use Cwd; 

my $scriptDir = dirname($0); 
chdir($scriptDir); 
print "First: $scriptDir\n"; 
$scriptDir = getcwd(); 
print "Second: $scriptDir\n"; 

wyjściowa:

[email protected]:~/Desktop$ perl test.pl 
First: . 
Second: /home/chankeypathak/Desktop 
0

nie jestem obok Perl monger, ale starałem się wykonać kod dałeś z małą skryptu:

#!/usr/bin/perl 
# 

use strict; 
use File::Basename; 
use Cwd; 

BEGIN { 
    my $scriptDir = dirname($0); 
    print "scriptDir = $scriptDir\r\n"; 
    chdir($scriptDir); 
    $scriptDir = getcwd(); 
    print "scriptDir = $scriptDir\r\n"; 
} 

i to, co wyszedł:

[email protected]:~/perltest> ./script.pl 
scriptDir = . 
scriptDir = /home/map/perltest 
[email protected]:~/perltest> 

To lo OK jak w przypadku dirname i getcwd robi różnicę w tym przypadku. Jeśli jednak scrip.pl znajduje się w ścieżce nie ma różnicy:

[email protected]:~> cp script.pl ~/bin 
[email protected]:~> cd 
[email protected]:~> script.pl 
scriptDir = /home/map/bin 
scriptDir = /home/map/bin 
[email protected]:~> rm ~/bin 
Powiązane problemy