【发布时间】:2017-01-31 10:51:18
【问题描述】:
我希望在这个小型代码项目上获得一些帮助或“第二双眼睛”。 我负责修复一些旧的 Perl 代码,这些代码将在新的 Web 服务器上运行。 该代码以秒为单位(自 1970 年以来)花费时间,连接破折号,连接服务器进程 ID 号以创建可变长度文件名。然后在许多下游流程中使用该文件和名称。
文件名创建代码为:$output_file = "$time-$$";
我遇到的问题是,在新服务器上,PID 最多可以是 6(或 7?)位,而旧服务器从未见过超过 5 位的 PID。其余的下游 perl 脚本都希望该 PID 文件名部分最多包含 5 位数字(当文件名的 PID 部分遇到 6 位数字时,程序会不正常地退出)。
所以我想要完成的是最终得到一个文件名,它始终是 16 个字符的固定长度。由 10 位时间码、一个破折号和一个 5 位 PID 号(如果 PID 大于 5 个字符,则为最右边的 5 位)组成。
我尝试创建一个 Perl 测试脚本来查看是否可以处理 PID 数据值。 (a) 如果是 6 位或 7 位字符,则使用 substr 命令将 PID 数据修剪为 5, (b) 或者如果小于 5,则增加到 5 个带前导零的字符,再次使用 substr 命令。 (a) 缩短它的情况似乎可以正常工作, 但是 (b) 试图使其更大的情况在服务器上的行为不一致。
如果可能的话,我想避免使用 grep 和正则表达式。 任何对我或其他支持人员以后难以破译的东西都没有用。
我的测试脚本的结构允许我确保我的所有测试用例都会产生正确的预期结果。 (而且我可能正在做一些完全错误/愚蠢的事情......)
我正在粘贴: (a) 我的测试脚本,(b) 服务器结果的屏幕快照。 服务器 PERL 版本:5.10.1
#!/usr/bin/perl -w
use strict;
use warnings;
#
# Name: testsubstr2.pl
#
my $pidnum7 = "1234567";
my $pidnum6 = "123456";
my $pidnum5 = "12345";
my $pidnum4 = "1234";
my $pidnum3 = "123";
my $pidnum2 = "12";
my $pidnum1 = "1";
if ( length( $pidnum7 ) == 7 )
{ print "This is 7 char PIDnum7. Length = ", length( $pidnum7 ), ", Content: ", $pidnum7, "\n";
my $subst7 = substr ($pidnum7, -5, 5);
print " Now shortened as SUBst7 to: ", length($subst7), ", Content: ", $subst7, "\n";
print " Orig PIDnum7 is length: ", length($pidnum7), ", Content: ", $pidnum7, "\n";
}
else { } # do nothing
# this 7 down to 5 seems to work ok.
#elsif ( length( $pidnum6 ) == 6 )
if ( length( $pidnum6 ) == 6 )
# else the string is 6 (or less)
{ print "This is 6 char PIDnum6. Length = ", length( $pidnum6 ), ", Content: ", $pidnum6, "\n";
my $subst6 = substr ($pidnum6, -5, 5);
print " Now shortened as SUBst6 to: ", length($subst6), ", Content: ", $subst6, "\n";
print " Orig PIDnum6 is length: ", length($pidnum6), ", Content: ", $pidnum6, "\n";
}
else { } # do nothing
# this 6 down to 5 seems to work ok.
#elsif ( length( $pidnum5 ) == 5 )
if ( length( $pidnum5 ) == 5 )
# else the string is exactly 5, do nothing
{ print "This PIDnum5 is exactly 5 char PIDnum, Length = ", length( $pidnum5 ), ", Content: ", $pidnum5, "\n";
}
else { } # do nothing. Fine as is.
#elsif ( length( $pidnum4 ) == 4 )
if ( length( $pidnum4 ) == 4 )
# else the string is 4, too short
{ print "This is 4 char PIDnum4. Length = ", length( $pidnum4 ), ", Content: ", $pidnum4, "\n";
my $subst4 = substr ($pidnum4, 0, 0, "0"); #insert character '0' in front
print " After substr command, PIDnum4 = ", length($pidnum4), ", Content: ", $pidnum4, "\n";
print " Now PID4 in variable SUBst4 is length: ", length($subst4), ", Content: ", $subst4, "\n";
# Weird Result in this code block, the var $pidnum4 becomes 5 chars, 01234, though it should not have changed
# but the temp var $subst4 becomes 0 charcters with Blank (no) content. It should I thought become the 5 character receiver.
# something wrong with this block of code.
}
else { } # do nothing
这是我的测试脚本运行的 Snaggy 链接server test results
(结果屏幕底部的 7 行来自我在测试脚本中包含的一些通用 substr 命令示例,可能不需要,因此我将它们排除在上面的代码示例之外。)
谢谢。
【问题讨论】:
-
这闻起来像
XY problem- 你想完成什么? Timestamp 是文件元数据,因此您不需要将其包含在文件名中。pid通常是独一无二的东西。那么……为什么不改用Data::UUID或File::Temp呢? -
我的限制是这个网站和 Perl 脚本系统是在 90 年代后期开发的,以创建一个有保证的唯一文件名。因此,以秒为单位的时间加上一个 PID 号。这个名字本身没有特别的意义。由于有许多脚本函数和 HTML 编码页面需要这种文件名形式,并且如果 PID 部分长于 5 位,则无法处理文件名,所以我坚持让它工作。我没有获得(母公司非营利组织的)mgnt 团队的授权来重新编码整个网站。所以——必须尽我所能。
-
加上当前生产网站上已经存在的数千个使用这种名称形式的数据文件。不过,这是一个值得提出的有效问题,希望原始编码人员对此的思考能够更加广泛。