Perl Cwd::cwd 和 Cwd::getcwd 函数有何不同?

2024-01-04

问题

有什么区别Cwd::cwd and Cwd::getcwd一般来说,在 Perl 中,不考虑任何特定平台?为什么 Perl 两者兼而有之?预期用途是什么,在什么场景下应该使用哪一种? (我们将不胜感激示例用例。)这重要吗? (假设我不混合它们。)选择其中任何一个会以任何方式影响可移植性吗?模块中哪一种更常用?

即使我解释手册是说除了极端情况cwd is `pwd` and getcwd只是打电话getcwd from unistd.h,实际差异是什么?无论如何,这只适用于 POSIX 系统。

我总是可以阅读实现,但这并没有告诉我这些函数的含义。实现细节可能会改变,而不是这么定义的意思。 (否则就会发生重大变化,这是一件很严重的事情。)

手册怎么说

引用 Perl 的Cwd 模块联机帮助页 http://perldoc.perl.org/Cwd.html:

这些函数中的每一个都在不带参数的情况下调用,并返回当前工作目录的绝对路径。

  • getcwd

    my $cwd = getcwd();

    返回当前工作目录。

    公开 POSIX 函数 getcwd(3) 或重新实现它(如果它不可用)。

  • cwd

    my $cwd = cwd();

    cwd() 是当前架构最自然的形式。对于大多数系统来说,它与“pwd”相同(但没有尾随行终止符)。

在注释部分:

  • 实际上,在 Mac 操作系统上,getcwd(), fastgetcwd() and fastcwd()函数都是别名cwd()函数,在 Mac OS 上称为“pwd”。同样,abs_path()函数是一个别名fast_abs_path()

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 Classic Mac OS, not OS X. $^O values are MacOS and darwin for Mac OS and OS X, respectively. Thanks, @tobyink /users/1990570/tobyink and @ikegami /users/589924/ikegami.

And a little meta-question: How to avoid asking similar questions for other modules with very similar functions? Is there a universal way of discovering the difference, other than digging through the implementation? (Currently, I think that if the documentation is not clear about intended use and differences, I have to ask someone more experienced or read the implementation myself.)


一般来说

我认为这个想法是cwd()始终解析为获取当前工作目录的外部、特定于操作系统的方式。也就是说,运行pwd在Linux上,command /c cd在DOS下,/usr/bin/fullpath -t在 QNX 等中 - 所有示例均来自实际Cwd.pm. The getcwd()应该使用 POSIX 系统调用(如果可用),然后回退到cwd() if not.

为什么我们两者都有?在当前的实施中,我相信导出只是getcwd()对于大多数系统来说就足够了,但是谁知道为什么“如果系统调用可用,则使用它,否则运行”的逻辑cwd()” 在某些系统上可能会失败(例如Perl 5.6.1 中的 MorphOS http://www.nntp.perl.org/group/perl.perl5.porters/2004/08/msg94261.html).

On Linux

在 Linux 上,cwd()会跑`/bin/pwd`(将实际执行二进制文件并获取其输出),而getcwd()将发行getcwd(2)系统调用。

实际效果通过查看strace

一个可以用strace(1)看看它的实际效果:

Using 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

Using getcwd():

$ strace -f perl -MCwd -e 'getcwd(); ' 2>&1 | grep execve
execve("/usr/bin/perl", ["perl", "-MCwd", "-e", "getcwd(); "], [/* 27 vars */]) = 0

Reading Cwd.pm source

您可以查看来源(Cwd.pm https://metacpan.org/source/SMUELLER/PathTools-3.47/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;
    }
}

性能基准

最后,两者的区别在于cwd(),它调用另一个二进制文件,一定会更慢。我们可以进行某种性能测试:

$ time perl -MCwd -e 'for (1..10000) { cwd(); }'

real    0m7.177s
user    0m0.380s
sys     0m1.440s

现在将其与系统调用进行比较:

$ time perl -MCwd -e 'for (1..10000) { getcwd(); }'

real    0m0.018s
user    0m0.009s
sys     0m0.008s

讨论、选择

但是,由于您通常不会太频繁地查询当前工作目录,因此这两个选项都可以工作 - 除非您由于某些与以下相关的原因无法生成更多进程ulimit、内存不足的情况等。

最后,至于选择使用哪一个:对于 Linux,我总是使用getcwd()。我想如果你要编写一段可移植的代码并在一些非常奇怪的平台上运行(当然,这里不包括 Linux、OS X 和 Windows),你将需要进行测试并选择要使用的函数。奇怪的平台列表)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Perl Cwd::cwd 和 Cwd::getcwd 函数有何不同? 的相关文章

随机推荐

  • 如何在Plone 5上自定义folder_contents?

    我在 Plone 5 上 我想修改默认显示的列数 folder contents 如果我没记错的话 整个table是一种在相应标签上使用相当大的 JSON data xxx 参数进行初始化的模式 那么 我应该深入研究 JSON 还是将注意力
  • 使用 jQuery 绘制动画线条

    我想使用 jQuery 来创建就像用隐形笔绘制线条图的效果 有点像这样 http d2fhka9tf2vaj2 cloudfront net tuts 152 QTiPad Milestones JavaScriptWebsite html
  • 如何修复 facebook Messenger-checkbox 的 CSP 问题

    我正在努力使Facebook Messenger 复选框 https developers facebook com docs messenger platform plugin reference checkbox plugin工作 我已
  • SKLabelNode没有透明背景

    您好 我在 SKLabelNode 上使用自定义字体 我可以设置字体颜色 但是还可以 但是文本的内部部分是透明的 例如 有什么方法可以将这种颜色设置为白色吗 到目前为止我的代码 scoreLabel fontColor SKColor co
  • 发布集合和 ModelState

    我的 MVC 应用程序中有一个问题 我不确定如何解决 或者我是否以错误的方式解决它 我有一个控制器 视图 它在带有复选框的网格中显示项目列表 当这些项目发布到我的控制器时 我想根据传入的 id 从数据库中删除行 该视图看起来像这样 for
  • 强制 IE9 使用浏览器模式而不是兼容模式

    我在用 in head标签 但是 当我在 IE9 上运行我的应用程序时 它使用浏览器模式 IE 9 紧凑视图 我希望我的应用程序仅使用浏览器模式 IE9 not 兼容视图 我意识到我在这方面有点晚了 但这是我使用过的并且它对我有用 确保这是
  • html5画布中的“擦除”

    我在 html5 canvas 中有一个涂鸦应用程序 我正在尝试找出实现橡皮擦控件的最佳方法 第一个冲动只是让橡皮擦绘制背景颜色 白色 但这是有问题的 因为如果用户将图像或另一层移动到他们之前擦除的位置 他们会在擦除的位置看到白色绘图 理想
  • FetchXml 中的左连接?

    如何使用 FetchXml 进行左连接 考虑一个简单的 SQL 查询 如下所示 select person name address city from person left join address on person addressi
  • QToolTip 中包含的变量不会自动更新

    我在 QLineEdit 上有一个 QToolTip 并且工具提示包含文本中的变量 工具提示代码包含在 init h 文件中 问题是工具提示中的变量值在程序运行中发生更改时不会自动更新 例如 我将鼠标悬停在行编辑上 值会显示在工具提示中 我
  • 在 JavaScript 中为属性添加别名

    我认为这很简单 有没有一种简单的方法来添加属性的辅助名称 我认为这是特定于字符串的 我不确定 即 c length this line pseudo code hello world length returns 11 hello worl
  • Scala Slick 2 加入多个字段?

    如何在多个字段上进行连接 如下例所示 val ownerId 1 val contactType 1 val contact for t c lt ContactTypes leftJoin Contacts on id typeId ow
  • XCode 4 与 Git/Github 无法提交图像

    源代码文件已提交 但图像未提交 错误信息 错误 pathscpec 与 git 已知的任何文件都不匹配 XCode 发行说明提到现在提交二进制文件存在问题 他们建议 在收到该错误后 您应该转到命令行并执行 git commit
  • JavaScript同步执行

    我是 javascript 新手 正在尝试使用滑块 我的问题类似于以下问题jquery attr 带回调 https stackoverflow com questions 4040712 jquery attr with callback
  • 在 Azure SQL DB 中启用和配置 FILESTREAM

    如何在 AZURE SQL DB 中存储 PDF 文件 上述要求我在 Azure SQL DB 上启用和配置 FILESTREAM 目前 当我运行创建表查询时出现此错误 Msg 40517 Level 16 State 1 Line 28
  • 数据列表分页?

    我有一个包含动态内容的数据列表 我需要启用对此数据列表的分页 我在 Visual Studion 2010 下使用 asp net c 请向我发送如何启用对数据列表分页的代码 这是数据列表的代码
  • 第一次偶然异常发生在 XMLSerializer 的构造函数中[重复]

    这个问题在这里已经有答案了 可能的重复 XmlSerializer 在构造函数中给出 FileNotFoundException https stackoverflow com questions 1127431 xmlserializer
  • Github - 分叉一个私人仓库

    我已被添加到一个拥有一些私有存储库的组织 我需要向他们发送包含一些更改的拉取请求 但我不知道是否可以 我在 GitHub 上没有付费帐户 那么如何分叉该私有存储库来修改和发送拉取请求 正如 如果我将其他人的私人 Github 存储库分叉到我
  • “VkVertexInputBindingDescription”中“绑定”的目的是什么?

    https www khronos org registry vulkan specs 1 0 man html VkVertexInputBindingDescription html https www khronos org regi
  • 记录 WCF 消息大小

    我正在使用 WCF 通过网络发送一些 Linq 对象 我想使用消息日志记录或跟踪来记录消息大小 然而我不想 或者没有能力使用配置文件来设置它 我正在努力弄清楚如何以编程方式执行此操作 我不在乎这是否发生在客户端主机上 我控制两者 有人有这样
  • Perl Cwd::cwd 和 Cwd::getcwd 函数有何不同?

    问题 有什么区别Cwd cwd and Cwd getcwd一般来说 在 Perl 中 不考虑任何特定平台 为什么 Perl 两者兼而有之 预期用途是什么 在什么场景下应该使用哪一种 我们将不胜感激示例用例 这重要吗 假设我不混合它们 选择