一つ気になったのは…
for $file ( $ftp -> ls() )
{
$bar = file;
これはすべきでは$bar = $fileありません$bar = file(あなたのスクリプトは の先頭$にありませんfile)。それ以外の場合は、文字列fileを に入れているだけです$bar。
あなたの式の他の部分は次のとおりです。
$dst_dir =~ s/\$\&/\$bar/g; #so this is replacing \$\& with $src
$dst_pattern =~ s/\$\&/\$bar/g;
$dst_dirとの値は$dst_pattern? それが本当の質問です。
どこか$dst_dirで$dst_pattern設定されています。ここで、FTP のファイルをこれらの文字列に置き換えます。次に、次のことに気付きます。
$dst_dir1 = eval( $dst_dir );
$dst_file = eval( $dst_pattern );
$dst_dirと$dst_fileはある種のコマンドのように見えますか? 他になぜevalそれらで実行されるのですか?これら 2 つの文字列の値は何ですか? なぜそれらを介して実行するのevalですか?
何が起こっているかというと、これら 2 つのコマンドには文字列$&が含まれており、その文字列を ftp しているファイルに置き換えています。
$dst_dirに等しいとしましょう$ftp->get("$&")。コマンドから取得したファイル名$ftp->ls(それがその文字列に代入されていると仮定しましょうbar.txt。したがって、$dst_dir1に設定され$ftp->get("bar.txt");ます。
ループ全体を見ると、次のようになります。
for $file ( $ftp -> ls() )
{
$bar = file;
$dst_dir =~ s/\$\&/\$bar/g; #so this is replacing \$\& with $src
$dst_pattern =~ s/\$\&/\$bar/g;
$dst_dir1 = eval( $dst_dir );
$dst_file = eval( $dst_pattern );
}
別の問題が見えます。$&各ファイルをループして$dst_dir、毎回置き換えて$dst_patternいます。ただし、すべてのファイルに対してこれを行っていて、 と の元の値をリセットしていない場合は$dst_dir、$dst_pattern. つまり、ループを 2 回目に通過するときは、$dst_dirandは変更されません$dst_pattern。そして、他のすべての場合でも、ループを通過します。
また、置換が実際に機能したかどうかを確認することもeval、 の値をチェックして機能するかどうかを確認することもありません$@。
その上、あなたは設定use strict;しておらず、おそらくそうではありませんuse warnings;。
ループの新しいバージョンは次のとおりです。
for my $file ( $ftp->ls ) {
my $dist_dir = $dst_dir; # Make sure you don't futz with your
my $dist_pattern = $dst_pattern; # original templates!
# Check to make sure replacements work!
if ( not $dist_dir =~ s/\$\&/\$file/g ) {
die qq(Couldn't put file name "$file" into "$dist_dir");
}
if ( not $dist_pattern =~ s/\$\&/\$file/g ) {
die qq(Couldn't put file name "$file" into "$dist_pattern");
}
# Check for Eval!
my $dst_dir1;
my $dst_file1;
$dst_dir1 = eval( $dist_dir );
if ( "$@" ) {
die qq(Evaluation of `$dist_dir` failed!: $@ );
}
$dst_file1 = eval( $dist_pattern );
if ( "$@" ) {
die qq(Evaluation of '$dist_pattern' failed!: $@);
}
}
これは、置換が機能することを確認するためのチェックであり、毎回テンプレートを変更せずに保存することもできます。