Pal*_*lec 11 perl working-directory getcwd perl5
Cwd::cwd和Cwd::getcwdPerl有什么区别,一般来说,不考虑任何特定的平台?为什么Perl都有?什么是预期用途,我应该在哪些场景中使用?(示例用例将受到赞赏.)这有关系吗?(假设我不混合它们.)任何一个的选择是否会以任何方式影响可移植性?哪一个更常用于模块?
即使我解释手册说,除了极端情况cwd是`pwd`,并getcwd只是调用getcwd从unistd.h,有什么实际的区别?无论如何,这仅适用于POSIX系统.
我总是可以阅读实现,但这并没有告诉我这些函数的含义.实施细节可能会发生变化,而非定义的含义.(否则会发生重大变化,这是一项严肃的事情.)
引用Perl的Cwd模块手册页:
这些函数中的每一个都不带参数调用,并返回当前工作目录的绝对路径.
GETCWD
my $cwd = getcwd();返回当前工作目录.
暴露POSIX函数getcwd(3)或重新实现它(如果它不可用).
CWD
my $cwd = cwd();cwd()是当前架构最自然的形式.对于大多数系统,它与`pwd`相同(但没有尾随行终止符).
在Notes部分:
- 事实上,在Mac OS上的
getcwd(),fastgetcwd()和fastcwd()功能都为所有别名cwd()功能,其中,在Mac OS,调用`pwd`.同样,该abs_path()函数是别名fast_abs_path()
好的,我知道在Mac OS 1上没有区别getcwd(),cwd()因为两者实际上归结为`pwd`.但是在其他平台上呢?(我对Debian Linux特别感兴趣.)
1经典的Mac OS,而不是OS X. $^O值MacOS和darwin分别为Mac OS和OS X,.谢谢,@ tobyink和@ikegami.
还有一个小问题:如何避免为具有非常相似功能的其他模块提出类似的问题?除了深入实施之外,是否存在发现差异的通用方法?(目前,我认为如果文档不清楚预期的用途和差异,我必须要求更有经验的人或自己阅读实施.)
我认为这个想法cwd()总是解析为获取当前工作目录的外部特定于操作系统的方式.也就是说,pwd在Linux上,command /c cd在DOS上,/usr/bin/fullpath -t在QNX中运行,等等 - 所有示例都来自实际Cwd.pm.在getcwd()应该使用POSIX系统调用(如果可用),并回落到cwd()如果不.
为什么我们两个都有?在当前的实现中,我相信getcwd()对于大多数系统来说,导出就足够了,但谁知道为什么"if syscall可用,使用它,否则运行cwd()" 的逻辑可能在某些系统上失败(例如在Perl 5.6.1中的MorphOS上) .
在Linux上,cwd()将运行`/bin/pwd`(实际上将执行二进制并获取其输出),同时getcwd()将发出getcwd(2)系统调用.
strace人们可以strace(1)用来看到实际行动:
使用cwd():
$ strace -f perl -MCwd -e 'cwd(); ' 2>&1 | grep execve
execve("/usr/bin/perl", ["perl", "-MCwd", "-e", "cwd(); "], [/* 27 vars */]) = 0
[pid 31276] execve("/bin/pwd", ["/bin/pwd"], [/* 27 vars */] <unfinished ...>
[pid 31276] <... execve resumed> ) = 0
Run Code Online (Sandbox Code Playgroud)
使用getcwd():
$ strace -f perl -MCwd -e 'getcwd(); ' 2>&1 | grep execve
execve("/usr/bin/perl", ["perl", "-MCwd", "-e", "getcwd(); "], [/* 27 vars */]) = 0
Run Code Online (Sandbox Code Playgroud)
Cwd.pm来源您可以查看源代码(Cwd.pm例如,在CPAN中),并查看Linux cwd()调用是否映射到_backtick_pwd,如顾名思义,调用pwd反向引号.
以下是Cwd.pm我的评论片段:
unless ($METHOD_MAP{$^O}{cwd} or defined &cwd) {
...
# some logic to find the pwd binary here, $found_pwd_cmd is set to 1 on Linux
...
if( $os eq 'MacOS' || $found_pwd_cmd )
{
*cwd = \&_backtick_pwd; # on Linux we actually go here
}
else {
*cwd = \&getcwd;
}
}
Run Code Online (Sandbox Code Playgroud)
最后,两者之间的区别在于cwd(),调用另一个二进制文件,必须更慢.我们可以做一些性能测试:
$ time perl -MCwd -e 'for (1..10000) { cwd(); }'
real 0m7.177s
user 0m0.380s
sys 0m1.440s
Run Code Online (Sandbox Code Playgroud)
现在将它与系统调用进行比较:
$ time perl -MCwd -e 'for (1..10000) { getcwd(); }'
real 0m0.018s
user 0m0.009s
sys 0m0.008s
Run Code Online (Sandbox Code Playgroud)
但由于您通常不经常查询当前工作目录,因此两个选项都可以正常工作 - 除非由于某些原因ulimit(内存不足等)导致无法生成任何其他进程.
最后,至于选择使用哪一个:对于Linux,我会一直使用getcwd().我想你需要进行测试并选择使用哪个函数,如果你要编写一个可以在一些非常奇怪的平台上运行的可移植代码(当然,在这里,Linux,OS X和Windows不在奇怪的平台列表).
| 归档时间: |
|
| 查看次数: |
2496 次 |
| 最近记录: |