2009-09-25 15 views
48

tengo que comprobar si un archivo en el directorio principal de un usuario existe a fin de utilizar la comprobación del archivo:¿Cómo puedo encontrar el directorio personal de un usuario en Perl?

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

A pesar de que existe un archivo llamado foo.txt en el directorio inicial del usuario, Perl siempre se queja de que no hay tal archivo o directorio. Cuando reemplazo "~" con /home/jimmy (supongamos que el usuario es jimmy), Perl da el veredicto correcto.

¿Podría explicar por qué "~" no funciona en Perl y decirme cuál es el camino de Perl al buscar el directorio de inicio de un usuario?

+17

~ es una cosa cáscara. Es por eso que no funciona en Perl. :) –

Respuesta

63

~ es un bash -ismo en lugar de un perl -ismo, por lo que no está funcionando. Teniendo en cuenta que usted parece estar en un sistema de tipo UNIX, probablemente la solución más fácil es utilizar la variable $HOME medio ambiente, tales como:

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

Y sí, sé que el usuario puede cambiar su variable de $HOME entorno pero supongo que saben lo que están haciendo. Si no, que se merecen todo lo que obtienen :-)

Si desea hacerlo de la manera correcta , se puede mirar en File::HomeDir, que es una plataforma mucho más conocedores. Puede verlo en acción en la siguiente secuencia de comandos 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"; 
} 

y la transcripción:

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

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

Hay un par de problemas con esto: no todas las sesiones tienen configurado HOME, y no todo el sistema construye sus rutas como unix. File :: HomeDir le dará la respuesta correcta. –

+8

Nunca asuma cuando no lo necesite. Los programas útiles tienden a migrar.:) –

+0

A _really_ responder tarde a esto, pero podría ser útil para los lectores actuales - una alternativa es usar 'glob ('~/foo.txt')'. Esto tiene la ventaja de que también expandirá apropiadamente cosas como '~ user123/foo.txt'. Me doy cuenta de que OP mencionó específicamente el directorio de inicio, pero me encontré con esto cuando buscaba algo más genérico, y pensé que ayudaría a otros a seguir el mismo camino. – John

11

el directorio inicial de un usuario se almacena en /etc/passwd. La mejor manera de llegar a la información es la getpw* functions:

#!/usr/bin/perl 

use strict; 
use warnings; 

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

Para hacer frente a su problema específico, prueba este código:

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

File :: HomeDir no es un módulo principal, por lo que esta podría ser una buena opción si no desea agregar una dependencia. – CoverosGene

14

Puede glob la tilde, glob('~/foo.txt') debería funcionar. O puede usar el módulo File::Save::Home que también debería ocuparse de otros sistemas.

+6

¿Por qué el voto a favor? Ambos enfoques funcionan. Si hay un problema con ellos, me gustaría saber. – zoul

+0

Hola, soy solo un principiante, pero si tengo un .jpg en mi directorio personal Win 7 y ejecuto: print glob ('~/*. Jpg'); no hace nada pero si ejecuto: print glob ('Users/Daniel/*. jpg'); imprime: /Users/Daniel/JanesJinormousJugs.jpg – Literat

+0

Solución no portátil muy elegante. Si tiene un script perl que está escrito para ejecutarse específicamente en un entorno Linux (por ejemplo, puede usar scripts bash, entonces no está perdiendo nada al hacerlo de esta manera, ya que no es portátil) –

56

No estoy seguro de cómo todos se perdieron File::HomeDir. Es una de esas tareas difíciles que suenan fáciles porque nadie conoce todas las ridículas excepciones en las que tienes que pensar. No viene con Perl, por lo que debe instalarlo usted mismo.

Una vez conocido el directorio principal, construir el camino que usted necesita 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 use con 'File :: chdir' (my fav CPAN module):' ... use File :: chdir; {local $ CWD = home; if (-e $ file) {...}} ', independiente de la plataforma, bloquea la administración del directorio de trabajo local! –

Cuestiones relacionadas