2009-09-25 16 views
48

Ho bisogno di verificare se un file nella directory home di un utente esiste in modo da utilizzare il controllo del file:Come trovo la directory home di un utente in Perl?

if (-e "~/foo.txt") { 
    print "yes, it exists!" ; 
} 

Anche se c'è un file chiamato foo.txt nella directory home dell'utente, Perl sempre lamenta che non esiste un tale file o directory. Quando sostituisco "~" con /home/jimmy (supponiamo che l'utente sia jimmy), allora Perl dà il verdetto corretto.

Puoi spiegare perché "~" non funziona in Perl e dimmi qual è il modo in Perl per trovare la home directory di un utente?

+17

~ è una cosa shell. Ecco perché non funziona in Perl. :) –

risposta

63

~ è un bash -ismo anziché un perl -ism, motivo per cui non funziona. Dato che ti sembra di essere su un sistema UNIX-tipo, probabilmente la soluzione più semplice è quello di utilizzare la variabile $HOME ambiente, come ad esempio:

if (-e $ENV{"HOME"} . "/foo.txt") { 
    print "yes ,it exists!" ; 
} 

E sì, so che l'utente può cambiare il loro variabile $HOME ambiente ma suppongo che sappiano quello che stanno facendo. In caso contrario, si meritano tutto quello che ottengono :-)

Se si vuole farlo nel modo giusto , si può guardare in File::HomeDir, che è molto di più della piattaforma-savvy. Potete vederlo in azione nel seguente script chkfile.pl:

use File::HomeDir; 
$fileSpec = File::HomeDir->my_home . "/foo.txt"; 
if (-e $fileSpec) { 
    print "Yes, it exists!\n"; 
} else { 
    print "No, it doesn't!\n"; 
} 

e la trascrizione:

 
pax$ touch ~/foo.txt ; perl chkfile.pl 
Yes, it exists! 

pax$ rm -rf ~/foo.txt ; perl chkfile.pl 
No, it doesn't! 
+10

Ci sono un paio di problemi con questo: non tutte le sessioni hanno impostato HOME, e non tutto il sistema costruisce i loro percorsi come unix. File :: HomeDir ti darà la risposta giusta. –

+8

Non assumere mai quando non è necessario. I programmi utili tendono a migrare.:) –

+0

Una risposta molto realistica a questo, ma potrebbe essere utile per i lettori attuali - un'alternativa è usare 'glob ('~/foo.txt')'. Questo ha il vantaggio che espanderebbe correttamente anche cose come ~ ~ user123/foo.txt'. Mi rendo conto che l'OP ha menzionato specificamente la home directory, ma mi sono imbattuto in questo quando ho cercato qualcosa di più generico, e ho pensato che avrei aiutato gli altri a seguire lo stesso percorso. – John

11

La directory principale per un utente è memorizzato in /etc/passwd. Il modo migliore per ottenere le informazioni è la getpw* functions:

#!/usr/bin/perl 

use strict; 
use warnings; 

print "uid:", (getpwuid 501)[7], "\n", 
    "name:", (getpwnam "cowens")[7], "\n"; 

Per risolvere il tuo problema specifico, provare questo codice:

if (-e (getpwuid $>)[7] . "/foo.txt") { 
    print "yes ,it exists!"; 
} 
+1

File :: HomeDir non è un modulo principale, quindi questa potrebbe essere una buona opzione se non si desidera aggiungere una dipendenza. – CoverosGene

14

È possibile glob la tilde, glob('~/foo.txt') dovrebbe funzionare. Oppure puoi usare il modulo File::Save::Home che dovrebbe occuparsi anche di altri sistemi.

+6

Perché il downvote? Entrambi gli approcci funzionano. Se c'è un problema con loro, mi piacerebbe saperlo. – zoul

+0

Ciao, sono solo un principiante, ma se ho un .jpg nella mia home directory di Win 7 e corro: print glob ('~/*. Jpg'); non fa nulla ma se corro: print glob ('Users/Daniel/*. jpg'); stampa: /Users/Daniel/JanesJinormousJugs.jpg – Literat

+0

Soluzione non portatile molto elegante. Se si dispone di uno script perl scritto per funzionare specificamente in un ambiente Linux (ad es. Si esegue lo shell su script di bash, quindi non si sta perdendo nulla in questo modo, poiché si è già non portatili) –

56

Non sono sicuro di aver perso tutti File::HomeDir. È uno di quei compiti difficili che sembrano facili perché nessuno conosce tutte le eccezioni sciocche a cui devi pensare. Non viene fornito con Perl, quindi è necessario installarlo da soli.

Una volta che si conosce la directory home, costruire il percorso che avete bisogno con File::Spec:

use File::HomeDir qw(home); 
use File::Spec::Functions qw(catfile); 

print "The path is ", catfile(home(), 'foo.txt'), "\n"; 
+0

o utilizzare con 'File :: chdir' (il mio modulo CPAN preferito):' ... usa File :: chdir; {locale $ CWD = casa; if (-e $ file) {...}} ', indipendente dalla piattaforma, blocca la gestione locale delle directory di lavoro! –

Problemi correlati