2009-09-25 5 views
48

мне нужно проверить, является ли файл в домашнем каталоге пользователя существует, так что используйте проверку файла:Как найти домашний каталог пользователя в Perl?

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

Даже если есть файл с именем foo.txt в домашнем каталоге пользователя, Perl всегда жалуется, что такого файла или каталога нет. Когда я заменяю «~» /home/jimmy (скажем, пользователь jimmy), то Perl дает правильный вердикт.

Не могли бы вы объяснить, почему «~» dosen't работает в Perl и рассказать мне, что такое путь Perl к найти домашний каталог пользователя?

+17

~ это оболочка вещь. Вот почему он не работает в Perl. :) –

ответ

63

~ - bash -ism, а не perl -ism, поэтому он не работает. Учитывая, что вы, кажется, в системе UNIX-типа, вероятно, решение простой является использование переменной $HOME среды, такие как:

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

И да, я знаю, что пользователь может изменить свою переменную $HOME среды но тогда я бы предположил, что они знают, что они делают. Если нет, то они заслуживают все, что они получают :-)

Если вы хотите сделать это право путь, вы можете посмотреть в File::HomeDir, что намного больше платформы подкованных. Вы можете увидеть его в действии в следующем сценарии 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"; 
} 

и расшифровка:

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

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

Есть пара проблем с этим: не все сессии имеют набор HOME, а не все системы строят их пути, такие как unix. Файл :: HomeDir даст вам правильный ответ. –

+8

Никогда не предполагайте, когда вам это не нужно. Полезные программы имеют тенденцию мигрировать.:) –

+0

_really_ поздно ответить на это, но это может быть полезно для текущих читателей - альтернативой является использование 'glob ('~/foo.txt')'. Это имеет то преимущество, что оно правильно расширяет такие вещи, как '~ user123/foo.txt'. Я понимаю, что ОП конкретно упоминал домашний каталог, но я столкнулся с этим, когда искал что-то более общее, и думал, что помогу другим следовать по тому же пути. – John

11

домашний каталог пользователя хранится в /etc/passwd. Лучший способ получить в информации является getpw* functions:

#!/usr/bin/perl 

use strict; 
use warnings; 

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

Для решения вашей конкретной проблемы, попробуйте этот код:

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

Файл :: HomeDir не является основным модулем, поэтому это может быть хорошим вариантом, если вы не хотите добавлять зависимость. – CoverosGene

14

Вы можете glob тильды, glob('~/foo.txt') должен работать. Или вы можете использовать модуль File::Save::Home, который также должен заботиться о других системах.

+6

Почему downvote? Оба подхода работают. Если есть проблема с ними, я хотел бы знать. – zoul

+0

Привет Я просто новичок, но если у меня есть .jpg в моем домашнем каталоге Win 7, и я запускаю: print glob ('~/*. Jpg'); он ничего не делает. но если я запустил: print glob («Пользователи/Daniel/*. jpg»); он печатает: /Users/Daniel/JanesJinormousJugs.jpg – Literat

+0

Очень элегантное непереносимое решение. Если у вас есть скрипт perl, который написан для работы в среде linux (например, вы распространяете скрипты bash, то вы ничего не теряете, делая это таким образом, поскольку вы уже не переносимы) –

56

Я не уверен, как все пропустили File::HomeDir. Это одна из тех трудных задач, которые звучат легко, потому что никто не знает обо всех пустых исключениях, о которых вам нужно подумать. Он не поставляется с Perl, поэтому вам нужно установить его самостоятельно.

После того, как вы знаете, домашний каталог, построить путь, который вам нужно с File::Spec:

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

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

или используйте с 'File :: chdir' (my fav CPAN module):' ... использовать File :: chdir; {local $ CWD = home; if (-e $ file) {...}} ', независимый от платформы, блокировать управление локальным рабочим каталогом! –

 Смежные вопросы

  • Нет связанных вопросов^_^