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 コア モジュールCwdを使用することもできます。pwd

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

利点の 1 つは、Cwdより移植性が高いことですpwd

関連項目: Perl における UNIX の「コマンド」の同等物

于 2011-07-03T00:44:26.150 に答える
3

謎の可能な説明

pwdこれらの奇妙なことを行うコマンド検索パス(つまり、PATH環境変数によって指定されたディレクトリの1つ)に名前が付けられたプログラムがあります。インタラクティブシェル(bash)またはシェルスクリプト(ダッシュ)で実行pwdすると、buildinコマンドpwdが表示され、現在の作業ディレクトリが出力されます。

一方、Perlソース行では

$directory=`pwd`;

PerlはC関数を使用してシステムのシェルを呼び出すのではなく、コマンドが十分に単純に見えるため(bashの用語では単純なコマンド) 、パス内system()のコマンドを直接実行します(フォークされたプロセスでの呼び出しを使用)。このバイナリが通常のバイナリ(これも単に現在のディレクトリを出力します)ではなく、代わりにのようなことをする場合、観察された動作を取得します。pwdexecvp()pwd/bin/pwdls -l

本当の解決策pwdは、PATHを修正するか、偽のバイナリを削除することです。which pwdそれがどこにあるか(またはtype -a pwdbash上)を見つけるために使用します。

Perl側からの解決策は、シェル呼び出しを強制することです。

$directory=`pwd;`;

これにより、Perlはプログラムを直接実行するのではなく、シェルを呼び出すように強制されます。(より一般的には、シェルのメタ文字にはこの効果があります。これは、Perlのシステム関数についてのみ説明されており、quote-execute演算子については説明されていません。)

この場合、Perlはを呼び出し/bin/shます。これはUbuntuでは(少なくとも現在のバージョンでは、9.10についてはわかりません)、 (GNUのBourne Again Shell dash)ではなく(Debian Almquist Shell )です。Dashはbashbashよりもはるかに単純な(そしてより高速な)実装ですが、1つのシェルで定義されたエイリアスやシェル関数がなく、もう1つ。shpwd

もちろん、より良い解決策は、toolicによる回答で推奨されているように、 PerlのCwdモジュールを使用することです。


質問へのコメントでバックティック演算子のセマンティクスを説明してくれた池上に感謝します。

于 2011-07-04T23:58:03.027 に答える
3

ここでも問題なく動作します (SUSE Linux Enterprise Server)。$directoryの出力を吐き出す理由がわかりませんls

ETA: コマンド ラインからこれを実行します。

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

出力が何であるかを教えてください。

于 2011-07-03T00:29:35.100 に答える
1

それは私にとってもうまくいきます。シェルエイリアスまたはシェル関数と関係があるのではないかと思っています。次のように、コマンドを bash の別のコマンドにエイリアスできます。

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

エイリアスの詳細は次のとおりです: http://en.wikipedia.org/wiki/Alias_%28command%29

Perl プログラムによって実行されるシェル コマンドが、アクセスできるエイリアス セットとは異なるエイリアス セットにアクセスできる理由はわかりません。

このプログラムをコマンド ラインから実行していますか、それとも別のプロセスを介して実行していますか? (Apache ユーザー アカウントによって実行される CGI スクリプトなど)

外部コマンドと同じ名前のシェル関数を定義して、外部コマンドの代わりに実行することもできますが、コマンド ラインから直接通常の出力が得られる理由は説明されていません。

于 2011-07-03T00:33:20.970 に答える