Как я могу заставить Perl распознавать пути с помощью '~'?
Возможный дубликат:
Как найти домашний каталог пользователя в Perl?
Я использую Ubuntu.
Всякий раз, когда я передаю скрипт Perl, путь начинается с ~
(например ~/Documents/file.txt
) это не может найти его. Я должен пройти канонический путь (например, /home/dave/Documents/file.txt
).
Это почему?
Могу ли я заставить Perl узнать ~
пути?
ОБНОВИТЬ
Все предлагаемые решения включают изменение кода в скриптах. Я хотел бы найти решение, которое не повлекло бы за собой никаких изменений в самих скриптах (поскольку не все они мои). Может быть, что-то в стиле Bash?
Обновленная версия вопроса была размещена на Super User.
7 ответов
Для надежного (и простого) кроссплатформенного метода попробуйте File:: HomeDir:
use File::HomeDir;
print File::HomeDir->my_home;
Функция glob понимает стандартную глобализацию файлов Unix.
my $file = glob('~/Documents/file.txt');
Используйте угловые кавычки, а не двойные кавычки:
open(my $fh, "< :crlf :encoding(cp1252)",
<~/Documents/file.txt>)
|| die "couldn't open Winblose text file ~/Documents/file.txt: $!";
<xxx>
оператор итерации, который люди обычно считают синтаксическим сахаром для readline
функция, вместо этого вызывает glob
функционировать, если в xxx есть метасхемы оболочки, и тильда считается одним из них.
Вы можете предпочесть открытый режим <:encoding(Latin1)
, Это зависит только от файла.
Из комментария Бруно, вы можете сделать это следующим образом:
$path =~ s/^~(\w*)/ ( getpwnam( $1 || $ENV{USER} ))[7] /e;
e
Флаг заменяет выражение на результат выполнения или вычисления выражения замены.
Немного поздно, но простое решение — дважды экранировать пробелы в имени файла/пути, чтобы glob не ломался. Не уверен, что это переносимо, но это достаточно легко сделать на платформах, которые это поддерживают (может быть, даже в Windows?), а затем полученное значение, сохраненное в переменной var, позволяет легко использовать. Можно использовать регулярное выражение для замены пробелов в именах файлов двойной обратной косой чертой. Пример без регулярных выражений:
my $dir_name = "~/Shared\\ Items/a\\ filename\\ with\\ spaces.txt";
my $glob_name = glob($dir_name);
print "exists!\n" if -e $glob_name;