来自perl的奇怪`pwd`输出

时间:2011-07-03 00:13:56

标签: linux perl unix ubuntu pwd

我有一个非常简短的perl脚本教程:

#!/usr/bin/perl
print "The date is ",`date`;
print "The date is `date`",".\n";
$directory=`pwd`;
print "\nThe current directory is $directory.";

和输出:

The date is Sat Jul  2 17:04:58 PDT 2011
The date is `date`.

The current directory is total 20
-rwxr-xr-x 1 yan yan 433 2011-07-02 15:58 36
-rwxr-xr-x 1 yan yan 313 2011-07-02 16:29 43
-rwxr-xr-x 1 yan yan 116 2011-07-02 16:51 45
-rwxr-xr-x 1 yan yan 149 2011-07-02 16:53 46
-rwxr-xr-x 1 yan yan 145 2011-07-02 17:02 47

但是,如果我只是运行pwd,我得到了:

yan@ubuntu:~/bin/blackperl$ pwd
/home/yan/bin/blackperl

这里有什么合乎逻辑的解释?非常感谢!

4 个答案:

答案 0 :(得分:7)

我也无法解开这个谜团,但您可以尝试使用Perl Core模块Cwd而不是pwd命令:

use warnings;
use strict;
use Cwd;
my $dir = getcwd();
print "$dir\n";

一个优点是Cwdpwd更便携。

另请参阅:UNIX 'command' equivalents in Perl

答案 1 :(得分:3)

神秘的可能解释

在命令搜索路径中有一些名为pwd的程序(即在PATH环境变量命名的目录之一中),它执行这些奇怪的操作。在交互式shell(bash)或shell脚本(破折号)中执行pwd时,您将获得buildin命令pwd,它会打印当前工作目录。

另一方面,在你的Perl源代码行

$directory=`pwd`;

Perl不使用C system()函数调用系统的shell,而是直接在路径中执行pwd命令(在分叉进程中使用execvp()调用),因为命令看起来很简单(一个简单的命令,在bash术语中)。如果这个pwd二进制文件不是通常的/bin/pwd二进制文件(它也只是打印当前目录),而是执行ls -l之类的操作,我们会得到观察到的行为。

真正的解决方案将修复您的PATH和/或删除伪造的pwd二进制文件。使用which pwd找出它的位置(或bash上的type -a pwd)。

来自Perl方的解决方案将强制进行shell调用:

$directory=`pwd;`;

这会强制Perl调用shell而不是直接执行程序。 (更一般地说,任何 shell元字符都有这种效果。这仅针对Perl的system function而不是quote-execute operator进行描述。)

在这种情况下,Perl会调用/bin/sh,在Ubuntu中(至少在当前版本中,我不确定你的9.10)是dash(Debian Almquist Shell)而不是{{1} (GNU的Bourne Again Shell)。 Dash是一个比bash更简单(更快)bash的实现,但对于像sh这样的东西应该没有区别(它也是我的破折号中的buildin),只要你没有在一个shell中定义的别名或shell函数,而不是另一个。

当然,更好的解决方案将使用Perl的Cwd模块,recommended in the answer by toolic


感谢ikegami在问题评论中向我解释反对操作符的语义。

答案 2 :(得分:2)

此处也正常(SUSE Linux Enterprise Server)。我不知道为什么$directory会吐出ls的输出。

ETA:从命令行运行:

perl -e 'print "$ENV{PWD}\n";'

告诉我输出是什么。

答案 3 :(得分:1)

它对我也很好。我想知道它是否与shell别名或shell函数有关。您可以使用bash将命令别名替换为另一个命令:

doug@supermicro:~$ alias pwd='ls -la'

以下是别名:http://en.wikipedia.org/wiki/Alias_%28command%29

虽然我无法想到为什么Perl程序运行的shell命令可以访问您有权访问的集合中的一组不同的别名。

您是从命令行运行此程序还是通过其他进程运行该程序? (例如由Apache用户帐户运行的CGI脚本)

您还可以使用与外部命令相同的名称定义shell函数,而不是外部命令,但这并不能解释为什么直接从命令行获得正常输出。