我有一个非常简短的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
这里有什么合乎逻辑的解释?非常感谢!
答案 0 :(得分:7)
我也无法解开这个谜团,但您可以尝试使用Perl Core模块Cwd而不是pwd
命令:
use warnings;
use strict;
use Cwd;
my $dir = getcwd();
print "$dir\n";
一个优点是Cwd
比pwd
更便携。
答案 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函数,而不是外部命令,但这并不能解释为什么直接从命令行获得正常输出。