example file Ответов: 1

Почему мои аргументы командной строки выдают ошибку?


я попытался прочитать текстовый файл с помощью командной строки aruments и передать его в подпрограмму, но он выдает ошибку с помощью perl?

Ошибка:

Use of uninitialized value in opendir at ./generate.pl line 50.
Use of uninitialized value in concatenation (.) or string at ./generate.pl line 50.
Can't open : No such file or directory at ./generate.pl line 50.


Исполнение должно быть следующим:

./generate.pl -prjroot "/home/rpsa/EMO/ct_space" -outdir "/home/rpsa/output" -mapfile "/home/rpsa/EMO/mapfile.txt"


Что я уже пробовал:

#!/usr/local/bin/perl
use strict;
use warnings 'all';
#use CGI qw(:all);
#generate the user file arguments

use File::Path       qw( make_path );
use File::Copy  qw( copy move);
use File::Find::Rule qw( );
use File::Remove();
use Cwd qw(getcwd);
use File::Basename;
use File::Copy ();
use File::Remove();
use File::Basename;
 
 use Getopt::Long 'GetOptions';
GetOptions(
    'prjroot=s' => \my $input_dir,
    'outdir=s'  => \my $output_dir,
   'mapfile=s' => \my $mapfile,
);
##COPYING THE CONFIG FILES FROM SOURCE TO DESTINATION### 
my %created;
for my $in (
   File::Find::Rule
   ->file()
   ->name(qr/^[^.].*\.config$/)
   ->in($input_dir)
) {
   my $match_file = substr($in, length($input_dir) + 1); 
   my ($match_dir) = $match_file =~ m{^(.*)/} ? $1 : '.';
   my $out_dir = $output_dir . '/' . $match_dir;
   my $out     = $output_dir . '/' . $match_file;
   make_path($out_dir) if !$created{$out_dir}++;
   copy($in, $out);
}
##READ THE TEXT FILE AND RENAME THE DIRECTORIES ####
my $dir_map = read_map($ARGV[2]);
print $dir_map;
#my $top_dir = '.';
my $top_dir=$ARGV[1];

rename_dirs( $top_dir, $dir_map );

 sub rename_dirs {
 #print "process started for renaming directories";
    my ( $top_dir, $dir_map ) = @_;

    opendir (my $dh, $top_dir) or die "Can't open $top_dir: $!";
    my $save_dir = getcwd();
    chdir $top_dir;
    while (my $dir = readdir $dh) {
        next if ($dir eq '.') or ($dir eq '..'); 
        if ( exists $dir_map->{$dir} ) {
            my $new_name = $dir_map->{$dir};
            #say "$save_dir: rename $dir $new_name";
            File::Copy::move( $dir, $new_name )
                or die "Could not rename '$dir' as '$new_name': $!";
            $dir = $new_name;
        }
        rename_dirs( $dir, $dir_map ) if -d $dir;

    }
    chdir $save_dir;

}
##SUB ROUTINE TO READ THE TEXT FILE FROM COMMAND LINE ARGUMENTS##
sub read_map {
#print "read the text file \n";
    my ( $fn ) = @_;

    my %dir_map;

    open( my $fh, '<', $ARGV[2] ) or die "Could not open file '$fn': $!";
    while( my $line = <$fh> ) {
        chomp $line;
        my @fields = split /:/, $line;
        if ( @fields == 3 ) {
            $dir_map{$fields[2]} = $fields[1];
        }
    }
    close $fh;
    return \%dir_map;
}

Jochen Arndt

Вы должны показать код вокруг строки 50 (и указать эту строку).
То, что вы показали, не является кодом, который генерирует ошибку, потому что он не содержит вызова opendir().

example file

я обновил свой код,можете ли вы просмотреть его сейчас

Richard MacCutchan

    opendir (my $dh, $top_dir) or die "Can't open $top_dir: $!";

В чем заключается ценность $dh?

example file

$dh - это имя дескриптора файла, в котором будет храниться содержимое из $top_dir(т. е. текущее местоположение я должен передать его в качестве аргументов командной строки, в которых входные данные должны приниматься из пути выполнения [т. е. outdir "/home/rpsa/output"].

Richard MacCutchan

Похоже, что это строка кода, на которую ссылается сообщение об ошибке, поэтому одна из этих переменных не имеет значения. Вам нужно сделать некоторую отладку, чтобы выяснить, почему.

Jochen Arndt

Переменная $top_dir не инициализируется.
Возможно, вы вызвали свой скрипт без аргументов строки comamnd ($ARGV[1] Не задан).

example file

я попытался исправить это, но не смог найти решение.

Richard MacCutchan

Исправить что? Если вы не предоставите правильных подробностей вашей проблемы, невозможно предложить какие-либо предложения.

example file

проблема, которая у меня есть, заключается в том, что я не знаю, как передать файл-mapfile [т. е. home/rpsa/DEMO/mapfile.txt`] в качестве аргументов внутри perl script.so я попробовал $ARGV[2], который был выделен жирным шрифтом .Из-за этих проблем я сталкиваюсь с ошибкой при чтении mapfile.txt

1 Ответов

Рейтинг:
5

Jochen Arndt

Вы используете GetOptions в одном месте и получить доступ к аргументам командной строки через $ARGV в других местах. При использовании GetOptions, все совпадающие аргументы удаляются из $ARGV[].

Поэтому при выполнении скрипта с

./generate.pl -prjroot "/home/rpsa/EMO/ct_space" -outdir "/home/rpsa/output" -mapfile "/home/rpsa/EMO/mapfile.txt"
там будет только $ARGV[0] слева (выполненная команда).

Решение:
Замените все виды использования $ARGV[] по совпадающим переменным, заданным GetOptions.