1

我有一个非常简短的教程 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

4 回答 4

7

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

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

一个优点是它Cwdpwd.

另请参阅:Perl 中的 UNIX“命令”等效项

于 2011-07-03T00:44:26.150 回答
3

它在这里也可以正常工作(SUSE Linux Enterprise Server)。我不知道为什么$directory会吐出ls.

ETA:从命令行运行:

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

并告诉我输出是什么。

于 2011-07-03T00:29:35.100 回答
3

这个谜的可能解释

您有一些pwd在命令搜索路径中命名的程序(即在 PATH 环境变量命名的目录之一中)执行这些奇怪的事情。在pwd交互式 shell (bash) 或 shell 脚本 (dash) 中执行时,您会得到 buildin command pwd,它会按原样打印当前工作目录。

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

$directory=`pwd`;

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

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

Perl 方面的解决方案是强制执行 shell 调用:

$directory=`pwd;`;

这迫使 Perl 调用 shell 而不是直接执行程序。(更一般地说,任何shell 元字符都有这种效果。这仅针对 Perl 的系统函数进行描述,而不针对引用执行操作符。)

在这种情况下,Perl 会调用/bin/sh,在 Ubuntu 中(至少在当前版本中,我不确定你的 9.10 版本)是dash(Debian Almquist Shell)而不是bash(GNU 的 Bourne Again Shell)。Dash 是一种比 bash 更简单(且更快)的sh实现,但对于诸如此类的事情pwd应该没有区别(它也是我的 dash 中的一个内置函数),只要您没有在一个 shell 中定义别名或 shell 函数并且没有另一个。

当然,更好的解决方案是使用 Perl 的Cwd模块,如toolic 答案中所推荐的那样


感谢ikegami在问题的评论中向我解释了反引号运算符的语义。

于 2011-07-04T23:58:03.027 回答
1

它对我也很好。我想知道它是否可能与 shell 别名或 shell 函数有关。您可以将一个命令别名为 bash 中的另一个命令,如下所示:

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

这里有更多关于别名的信息:http ://en.wikipedia.org/wiki/Alias_%28command%29

虽然我想不出为什么 Perl 程序运行的 shell 命令可以访问与您有权访问的集合不同的别名集。

你是从命令行运行这个程序还是通过另一个进程运行它?(例如由 Apache 用户帐户运行的 CGI 脚本)

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

于 2011-07-03T00:33:20.970 回答