【问题标题】:Perl mis-behaves when a file is given as an argument当文件作为参数给出时,Perl 行为异常
【发布时间】:2015-03-30 03:09:20
【问题描述】:

您好,下面是我的 perl 代码:

#!/usr/bin/perl -w

no warnings;
use Env;

my $p4user = $ENV{'P4USER'};
my $current_path = $ENV{'PWD'};
print("\t Hello $p4user. You are currently in $current_path path.\n");

open($user_in,"$ARGV[0]") || die("failed to open the argument file $ARGV[0]\n");

print("\t To create a new client enter '1' |");
print("\t To use an existing client enter '2' : ... ");

my $cl_op = <>;
chop($cl_op);

if (($cl_op == 1) || ($cl_op == 2))
{
  # do something common for both condition

  if ($cl_op == 1)
  {
    # do something
  }
  elsif ($cl_op == 2)
  {
  # do something
}
}
else
{
  die("\n\t Sorry. Invalid option : $cl_op\n");
}

然后脚本运行如下:

     Hello biren. You are currently in /remote/vgvips18/biren/tcf_4nov path.

     Sorry. Invalid option : ###################################################################
     To create a new client enter '1' |      To use an existing client enter '2' : ... 

知道为什么脚本会这样。当我注释掉这一行时“

打开($user_in,"$ARGV[0]") || die("打开参数文件失败 $ARGV[0]\n");

",脚本运行良好。 当我在命令行上将文件作为参数传递时,任何人都可以帮助解释为什么脚本的行为。

【问题讨论】:

  • 使用die("failed to open the argument file $ARGV[0]: $!\n") 获取有关打开失败原因的更多信息。也许该文件不存在或不可读?
  • 为什么禁用警告,为什么不使用严格?他们会指出脚本中的许多问题,并且应该始终包含在内。

标签: perl


【解决方案1】:
my $cl_op = <>;

这将读取您作为 arg 传递的文件的第一行。

要让它读取用户对您的提示的响应,请将其更改为:

my $cl_op = <STDIN>;

【讨论】:

    【解决方案2】:

    在尝试打开文件之前,最好包含完整性检查以验证文件名是否作为参数传递。

    my $user_in;
    if ( defined $ARGV[0] ) { 
       die "$ARGV[0] does not exist.\n" unless -e $ARGV[0];
       open($user_in,"$ARGV[0]") 
          or die("failed to open the argument file $ARGV[0]: $!\n");
    }
    

    【讨论】:

      【解决方案3】:

      &lt;&gt;&lt;ARGV&gt; 的简写,其中ARGV 是一个特殊的(即魔术)文件句柄,它可以表示来自命令行参数的文件名,或者STDIN(如果没有命令行参数) . Perl 将根据@ARGV 第一次使用时的内容来决定如何处理ARGV

      如果你想调用你的程序,比如

      perl my_script.pl userfile inputfile
      perl my_script.pl userfile < inputfile
      cat inputfile | perl my_script.pl userfile
      

      所有工作都一样,在引用ARGV 之前,您需要先使用@ARGV 的第一个元素。像这样:

      my $userfile = shift @ARGV;   # removes $ARGV[0] from front of @ARGV
      open $user_in, '<', $userfile or ...
      ...
      my $cl_op = <>;
      

      现在正在从您提供的第二个文件名或 STDIN 读取 $cl_op

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-06
        • 2020-09-30
        • 2022-01-15
        • 2020-03-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-10-14
        相关资源
        最近更新 更多