Причина, по которой abs_path
не обрабатывает его правильно, заключается в том, что "~" является оболочкой конструкции.Perl ничего не знает о том, что означает «~», он буквально воспринимает это как «каталог с именем« тильда »(~) в текущем рабочем каталоге».
Любая программа, для которой в качестве параметра указывается «~», фактически вместо этого получает реальный путь к каталогу из оболочки.
Чтобы иметь возможность использовать домашние каталоги из Perl, в Unix вы можете использовать $ENV{HOME}
вместо "~" для собственного домашнего каталога;или для других пользователей используйте (getpwnam($user))[7]
;нет и чистого кроссплатформенного способа сделать это.
Второй подход - использовать оболочку для грязной работы в системном вызове:
my $expanded_home_dir = `cd ~/mydir/; pwd`;
ОБНОВЛЕНИЕ:
Во-первых, очень хороший рецепт для прямой замены тильд-хоум-струн находится в "Perl Cookbook" (2-е изд), гл.7.3 «Расширение тильд в именах файлов».
Во-вторых, как упоминается в комментариях daxim, поскольку Perl 5.6, CORE::glob()
фактически автоматически заменяется на File::Glob::bsd_glob()
, который поддерживает GLOB_TILDE
флаг POSIX и, следовательно, может расширить тильды для вас.
Интересно, что как bsd_glob (в коде C, как в Perlmonks), так и File::HomeDir
, упомянутые Эндрю Кларком с умом, используют точно такую же логику, что и рецепт Cookbook 7.3 ($ENV{HOME}||$ENV{LOGDIR}||(getpwnam($<))[7]
) для сред Unix.