Perl Cwd :: cwd和Cwd :: getcwd函数有何不同? [英] How do Perl Cwd::cwd and Cwd::getcwd functions differ?
问题描述
通常,在不考虑任何特定平台的情况下,Perl中的Cwd::cwd
和Cwd::getcwd
有什么区别?为什么Perl两者都有?预期用途是什么?在哪种情况下应该使用哪种用途? (示例用例将不胜感激.)这有关系吗? (假设我没有混合使用.)选择其中一种会以任何方式影响便携性吗?模块中最常用的是哪一种?
What is the difference between Cwd::cwd
and Cwd::getcwd
in Perl, generally, without regard to any specific platform? Why does Perl have both? What is the intended use, which one should I use in which scenarios? (Example use cases will be appreciated.) Does it matter? (Assuming I don’t mix them.) Does choice of either one affect portability in any way? Which one is more commonly used in modules?
即使我理解手册的意思是,除了cwd
是`pwd`
和getcwd
的极端情况之外,只是从unistd.h
调用getcwd
,实际的区别是什么?无论如何,这仅适用于POSIX系统.
Even if I interpret the manual is saying that except for corner cases cwd
is `pwd`
and getcwd
just calls getcwd
from unistd.h
, what is the actual difference? This works only on POSIX systems, anyway.
我总是可以阅读实现,但是这些功能的含义并没有告诉我.实现细节可能会更改,而不是定义的含义. (否则会发生重大变化,这是很严肃的事情.)
I can always read the implementation but that tells me nothing about the meaning of those functions. Implementation details may change, not so defined meaning. (Otherwise a breaking change occurs, which is serious business.)
引用Perl的 Cwd模块手册页:
这些函数中的每个函数均不带参数调用,并返回当前工作目录的绝对路径.
Each of these functions are called without arguments and return the absolute path of the current working directory.
-
getcwd
getcwd
my $cwd = getcwd();
返回当前工作目录.
公开POSIX函数getcwd(3)或重新实现它(如果不可用).
Exposes the POSIX function getcwd(3) or re-implements it if it's not available.
cwd
my $cwd = cwd();
对于当前架构,cwd()是最自然的形式.对于大多数系统,它与`pwd`相同(但没有尾随终止符).
The cwd() is the most natural form for the current architecture. For most systems it is identical to `pwd` (but without the trailing line terminator).
在注释"部分:
- 实际上,在Mac OS上,
的别名.getcwd()
,fastgetcwd()
和fastcwd()
函数都是cwd()
函数的别名,在Mac OS上称为`pwd`.同样,abs_path()
函数是fast_abs_path()
- Actually, on Mac OS, the
getcwd()
,fastgetcwd()
andfastcwd()
functions are all aliases for thecwd()
function, which, on Mac OS, calls `pwd`. Likewise, theabs_path()
function is an alias forfast_abs_path()
好的,我知道在Mac OS 1 上,getcwd()
和cwd()
之间没有区别,因为两者实际上都归结为`pwd`
.但是在其他平台上呢? (我对Debian Linux特别感兴趣.)
OK, I know that on Mac OS1 there is no difference between getcwd()
and cwd()
as both actually boil down to `pwd`
. But what on other platforms? (I’m especially interested in Debian Linux.)
1 经典Mac OS,不是OSX.对于Mac OS和OS X,$^O
的值分别为MacOS
和darwin
. 谢谢, @tobyink 和 @ikegami .
1 Classic Mac OS, not OS X. $^O
values are MacOS
and darwin
for Mac OS and OS X, respectively. Thanks, @tobyink and @ikegami.
还有一个元问题:如何避免对功能非常相似的其他模块提出相似的问题?除了深入研究实现之外,还有发现差异的通用方法吗? (目前,我认为,如果文档尚不清楚预期用途和区别,我必须请经验丰富的人或亲自阅读实施.
推荐答案
一般来讲
我认为这样的想法是cwd()
始终解析为获取当前工作目录的外部特定于操作系统的方式.也就是说,在Linux上运行pwd
,在DOS上运行command /c cd
,在QNX中运行/usr/bin/fullpath -t
,依此类推-所有示例均来自实际的Cwd.pm
.如果getcwd()
可用,则应该使用POSIX系统调用,否则将退回到cwd()
.
Generally speaking
I think the idea is that cwd()
always resolves to the external, OS-specific way of getting the current working directory. That is, running pwd
on Linux, command /c cd
on DOS, /usr/bin/fullpath -t
in QNX, and so on — all examples are from actual Cwd.pm
. The getcwd()
is supposed to use the POSIX system call if it is available, and falls back to the cwd()
if not.
为什么我们两者都有?在当前的实现中,我相信对于大多数系统来说,仅导出getcwd()
就足够了,但是谁知道为什么如果系统调用可用,请使用它,否则运行cwd()
"的逻辑在某些系统上可能会失败(例如 ).
Why we have both? In the current implementation I believe exporting just getcwd()
would be enough for most of systems, but who knows why the logic of "if syscall is available, use it, else run cwd()
" can fail on some system (e.g. on MorphOS in Perl 5.6.1).
在Linux上,cwd()
将运行`/bin/pwd`
(实际上将执行二进制文件并获取其输出),而getcwd()
将发出getcwd(2)
系统调用.
On Linux, cwd()
will run `/bin/pwd`
(will actually execute the binary and get its output), while getcwd()
will issue getcwd(2)
system call.
一个人可以使用strace(1)
看到它的作用:
One can use strace(1)
to see that in action:
使用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
使用getcwd()
:
$ strace -f perl -MCwd -e 'getcwd(); ' 2>&1 | grep execve
execve("/usr/bin/perl", ["perl", "-MCwd", "-e", "getcwd(); "], [/* 27 vars */]) = 0
阅读Cwd.pm
来源
您可以看一下来源( Cwd.pm
,例如在CPAN中),发现对于Linux,cwd()
调用已映射到_backtick_pwd
,顾名思义,该命令在反引号中调用pwd
.
Reading Cwd.pm
source
You can take a look at the sources (Cwd.pm
, e.g. in CPAN) and see that for Linux cwd()
call is mapped to _backtick_pwd
which, as the name suggests, calls the pwd
in backticks.
这是Cwd.pm
的摘录,上面有我的评论:
Here is a snippet from Cwd.pm
, with my comments:
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;
}
}
性能基准
最后,两者之间的区别在于调用另一个二进制文件的cwd()
必须更慢.我们可以进行某种性能测试:
Performance benchmark
Finally, the difference between two is that cwd()
, which calls another binary, must be slower. We can make some kind of a performance test:
$ time perl -MCwd -e 'for (1..10000) { cwd(); }'
real 0m7.177s
user 0m0.380s
sys 0m1.440s
现在将其与系统调用进行比较:
Now compare it with the system call:
$ time perl -MCwd -e 'for (1..10000) { getcwd(); }'
real 0m0.018s
user 0m0.009s
sys 0m0.008s
讨论,选择
但是,由于您通常不经常查询当前工作目录,因此这两个选项都将起作用-除非您由于与ulimit
,内存不足等相关的原因而无法产生更多进程.
Discussion, choice
But as you don't usually query the current working directory too often, both options will work — unless you cannot spawn any more processes for some reason related to ulimit
, out of memory situation, etc.
最后,选择要使用的选项:对于Linux,我将始终使用getcwd()
.我想如果您要编写将在某些真正奇怪的平台上运行的可移植代码段(当然,此处不包含Linux,OS X和Windows,则需要进行测试并选择要使用的功能)奇怪的平台列表).
Finally, as for selecting which one to use: for Linux, I would always use getcwd()
. I suppose you will need to make your tests and select which function to use if you are going to write a portable piece of code that will run on some really strange platform (here, of course, Linux, OS X, and Windows are not in the list of strange platforms).
这篇关于Perl Cwd :: cwd和Cwd :: getcwd函数有何不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!