Perl Cwd :: cwd和Cwd :: getcwd函数有何不同? [英] How do Perl Cwd::cwd and Cwd::getcwd functions differ?

查看:561
本文介绍了Perl Cwd :: cwd和Cwd :: getcwd函数有何不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通常,在不考虑任何特定平台的情况下,Perl中的Cwd::cwdCwd::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() and fastcwd() functions are all aliases for the cwd() function, which, on Mac OS, calls `pwd`. Likewise, the abs_path() function is an alias for fast_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的值分别为MacOSdarwin. 谢谢, @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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆