gpt4 book ai didi

windows - Perl:与 Unix 相比,Windows 中的奇怪 Tie::File 行为

转载 作者:可可西里 更新时间:2023-11-01 12:03:03 26 4
gpt4 key购买 nike

我有这个使用 Tie::File 的 perl 脚本.
在 Linux(Ubuntu) 中,当我通过 Bash 调用脚本时,它按预期工作,但在 Windows 中,当我通过 Powershell 调用脚本时,它表现得很奇怪(检查下面的 P.S.)。

代码:

#!/usr/bin/perl -T

use strict;
use warnings;

use Tie::File;
use CommonStringTasks;

if ( @ARGV != 4 ) {
print "ERROR:Inadequate/Redundant arguments.\n";
print "Usage: perl <pl_executable> <path/to/peer_main.java> <peer_main.java>\n";
print " <score_file_index> <port_step_index>\n";
print $ARGV[0], "\n";
print $ARGV[1], "\n";
print $ARGV[2], "\n";
print $ARGV[3], "\n";
exit 1;
}

my $PEER_DIR = $ARGV[0];
my $PEER_FILE = $ARGV[1];
my $PEER_PACKAGE = "src/planetlab/app";
my $PEER_PATH = "${PEER_DIR}/${PEER_PACKAGE}/${PEER_FILE}";

# Check if args are tainted ...

# Check $PEER_PATH file permissions ...

open(my $file, "+<", "$PEER_PATH")
or
die("File ", $PEER_FILE, " could not be opened for editing:$!");

# Edit the file and change variables for debugging/deployment setup.
# Number demanglers:
# -flock -> arg2 -> 2 stands for FILE_EX
# Options (critical!):
# -Memory: Inhibit caching as this will allow record changes on the fly.
tie my @fileLines,
'Tie::File',
$file,
memory => 0
or
die("File ", $PEER_FILE, " could not be tied with Tie::File:$!");

flock $file, 2;

my $i = 0;
my $scoreLine = "int FILE_INDEX = " . $SCORE . ";";
my $portLine = "int SERVER_PORT = " . $PORT . ";";
my $originalScoreLine = "int FILE_INDEX =";
my $originalPortLine = "int SERVER_PORT =";

(tied @fileLines)->defer;

while (my $line = <$file>) {
if ( ($line =~ m/($scoreLine)/) && ($SCORE+1 > 0) ) {
print "Original line (score): ", "\n", $scoreLine, "\n";
chomp $line;
$line = substr($line, 0, -($scoreDigits+1));
$line = $line . (++$SCORE) . ";";
print "Editing line (score): ", $i, "\n", trimLeadSpaces($fileLines[$i]), "\n";
$fileLines[$i] = $line;
print "Line replaced with:\n", trimLeadSpaces($line), "\n";
next;
}
if ( ($line =~ m/($portLine)/) && ($PORT > 0) ) {
print "Original line (port): ", "\n", $portLine, "\n";
chomp $line;
$line = substr($line, 0, -($portDigits+1));
$line = $line . (++$PORT) . ";";
print "Editing line (port): ", $i, "\n", trimLeadSpaces($fileLines[$i]), "\n";
$fileLines[$i] = $line;
print "Line replaced with:\n", trimLeadSpaces($line), "\n";
last;
}

# Restore original settings.
if ( ($line =~ m/($originalScoreLine)/) && ($SCORE < 0) ) {
print "Restoring line (score) - FROM: ", "\n", $fileLines[$i], "\n";
$fileLines[$i] = " private static final int FILE_INDEX = 0;";
print "Restoring line (score) - TO: ", "\n", $fileLines[$i], "\n";
next;
}
if ( ($line =~ m/($originalPortLine)/) && ($PORT < 0) ) {
print "Restoring line (port) - FROM: ", "\n", $fileLines[$i], "\n";
$PORT = abs($PORT);
$fileLines[$i] = " private static final int SERVER_PORT = " . $PORT . ";";
print "Restoring line (port) - TO: ", "\n", $fileLines[$i], "\n";
last;
}
} continue {
$i++;
}

(tied @fileLines)->flush;

untie @fileLines;
close $file;


两个操作系统中的 perl 版本都是 5+(在带有 CPAN 模块的 Windows Active-State Perl 中)。
这可能是我打开文件句柄的方式吗?有什么想法吗?

P.S.:第一个版本有一个 while (<$file>)而不是 $line我用了 $_变量,但是当我这样做时,我有一种行为,即特定行不会被编辑,而是文件会附加一百个换行符左右,然后是(正确)编辑的行等等。我也有关于 $fileLines[$i] 的警告未初始化!很明显 Tie::File 有问题Windows 中的结构或其他我不知道的东西。更改后会发生同样不稳定的行为,并且在 Linux (Ubuntu) 中的行为再次符合预期。

最佳答案

OP 问题含糊不清,缺乏输入和预期输出。因此,我将简单地记下我的一些担忧:

首先,使用 Tie::File<$file>flock在同一个 handle 上似乎既矫枉过正又危险。我建议简单地使用 Tie::File迭代和编辑,例如:

#!/usr/bin/env perl

use strict;
use warnings;

use Tie::File;

tie my @lines, 'Tie::File', 'filename';

foreach my $linenum ( 0..$#lines ) {
if ($lines[$linenum] =~ /something/) {
$lines[$linenum] = 'somethingelse';
}
}

也许比内联编辑更好,如Tie::File允许,将文件复制到备份,使用 <$file> 遍历行,然后用旧名称写入新文件。

#!/usr/bin/env perl

use strict;
use warnings;

use File::Copy 'move';

my $infile = $ARGV[0];

move( $infile, "$infile.bak");

open my $inhandle, '<', "$infile.bak";
open my $outhandle, '>', $infile;

while( my $line = <$inhandle> ) {
if ($line =~ /something/) {
$line = 'somethingelse';
}
print $outhandle $line;
}

二、-MModule标志简单地转换为 use Module;在脚本的顶部。因此-MCPANuse CPAN; , 但是正在加载 CPAN模块对脚本没有任何作用。 CPAN.pm赋予脚本安装模块的能力。

第三,如果您提供示例输入、预期输出和精简脚本,清楚地显示此操作如何执行,同时仍然以与实际脚本相同的方式失败,我们将能够提供更好的帮助。

关于windows - Perl:与 Unix 相比,Windows 中的奇怪 Tie::File 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8111415/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com