2010-05-10 5 views
1

Скажем, у меня есть эта PERL "программа" под названием simple.pl:Perl 'система' сообщения об ошибках

#!/usr/bin/perl 
use xyz; # xyz is bogus and doesn't exist 

И я также иметь эту "программу", которая называется simple2.pl:

#!/usr/bin/perl 
system("simple.pl"); 

my $abc = `simple.pl`; 
printf("abc %s\n", $abc); 

как для системы, так и для обратной связи, я получаю это сообщение:

Can't exec "simple.pl": No such file or directory at scripts/perl/simple2.pl line 7. 
Can't exec "simple.pl": No such file or directory at scripts/perl/simple2.pl line 9. 

Не очень полезно для пользователя, вызывающего simple2.pl. Есть ли способ получить более полезное сообщение?

Примечание. simple.pl существует в текущем каталоге. Реальная проблема заключается в том, что simple.pl не компилируется. simple2 отвечает, говоря, что простого не существует. это вводящее в заблуждение сообщение.

Если бы у меня был способ захватить сообщение компиляции, которое было бы началом.

ответ

3

Да, проверьте, существует ли файл и является исполняемым, а если нет, напечатайте более описательное сообщение.

unless (-ex $filename) { 
    print "I am unable to execute file $filename."; 
} 
+0

Программа действительно существует. Проблема в том, что простой не компилируется, но в сообщении говорится что-то еще. – mmccoo

+0

nix это. Я и идиот – mmccoo

+0

@mmc: вы можете удалить недопустимые комментарии: нажмите на красный значок x, который справа от вашего имени и метки времени. – Ether

6

Это значит, что системе не удалось найти исполняемый файл с именем "simple.pl" в PATH. Если ваш simple.pl находится в текущем каталоге, вы можете попробовать изменить «simple.pl» на «./simple.pl».

На самом деле, я не вижу, как сделать это сообщение более наглядным. Если бы вы были perl, как бы вы сообщили об этой ошибке?

Кстати, я бы не попробовать запустить «simple2.pl» изнутри simple2.pl :)

+0

+1. Также мне смешно думать, что язык программирования отвечает за предоставление удобных сообщений об ошибках. – tster

+0

простой.pl действительно есть. Проблема в том, что он не компилируется. Сообщение, которое я получаю, не говорит, что оно не может компилироваться, а скорее, что программа не существует. вводит в заблуждение. Хороший улов. simple2 должен называть простой – mmccoo

+1

nix мой комментарий. Я идиот – mmccoo

1

Бонусные баллы для включения в warnings прагму! Имейте upvote!

Вы хотите использовать обратные выходы или qx// для захвата вывода внешней программы, а не system. Чтобы заменить собственное сообщение об ошибке, которое будет иметь смысл для пользователей (больше очков для вас!), То вы могли бы сделать что-то, как и в

#! /usr/bin/perl 

use strict; 
use warnings; 
no warnings 'exec'; 

chomp(my $abc = `simple2.pl`); 
if ($? == 0) { 
    printf("abc %s\n", $abc); 
} 
else { 
    die "$0: unable to calculate abc\n"; 
} 

В случае, если вы не знакомы, $? является

$ CHILD_ERROR
$?
Состояние, возвращенное последним закрытием трубы, команда обратного хода, успешный вызов wait или waitpid, или из оператора system.

Когда $? равно нулю, это указывает на успех.

Помните, что warnings прагма лексических, так, а не отключить предупреждения для всей программы, вы можете сделать это только для одного суб:

sub calculate_abc { 
    no warnings 'exec'; 

    # ... 
} 
1

Если вы пытаетесь выполнить то, что вы знаете, является Perl, почему бы не вызвать непосредственно интерпретатора, а не иметь дело с системой, зная, как выполнить файл?

my $file = 'simple.pl'; 

-e $file or die "file '$file' not found"; 

system "perl $file"; 
# or 
print `perl $file`; 

работать с той же установкой Perl, который работает ваш текущий сценарий:

system "$^X $file"; # or `$^X $file` 

$^X специальная переменная Perl, который содержит имя файла, запущенного интерпретатора.

2

Если perl говорит, что не может найти файл, он не может найти файл. И проблема - это скорее ваш код. Посмотрите на этот пример.

 
[email protected]:~/perl$ cat test.pl 
#!/usr/bin/env perl 
use strict; 
use warnings; 
use xyz; 
[email protected]:~/perl$ cat test2.pl 
#!/usr/bin/env perl 
use strict; 
use warnings; 
system('test.pl'); 
[email protected]:~/perl$ cat test3.pl 
#!/usr/bin/env perl 
use strict; 
use warnings; 
system('./test.pl'); 

Если вы выполняете test2.pl вы получите:

 
[email protected]:~/perl$ ./test2.pl 
Can't exec "test.pl": No such file or directory at ./test2.pl line 4. 

Если вы выполняете test3.pl вы получите:

 
[email protected]:~/perl$ ./test3.pl 
Can't locate xyz.pm in @INC (@INC contains: /home/sidburn/perl510/lib/5.10.1/i686-linux /home/sidburn/perl510/lib/5.10.1 /home/sidburn/perl510/lib/site_perl/5.10.1/i686-linux /home/sidburn/perl510/lib/site_perl/5.10.1 .) at ./test.pl line 4. 
BEGIN failed--compilation aborted at ./test.pl line 4. 

Если вы не обеспечивают относительный или абсолютный путь затем perl найдите команду в переменной среды $ PATH. Если его нет, он не может найти файл.

Вам необходимо указать «./», если оно находится в текущем каталоге. Но обратите внимание, что «текущий каталог» не означает каталог, в котором работает ваш скрипт.

Если вы хотите, чтобы позже, то вы, вероятно, хотите сделать

 
use FindBin; 

с этим вы можете сделать что-то вроде этого:

 
#!/usr/bin/env perl 
use strict; 
use warnings; 
use FindBin; 
use File::Spec::Functions; 

my $exe = catfile($FindBin::RealBin, 'test.pl'); 

print $exe, "\n"; 
system($exe); 

если вы хотите проверить, если система возвращается правильно, нужно проверить возвращаемое значение из команды system() или $? позже это значение.

 
if ($? != 0) { 
    die "Cannot execute $exe.\n"; 
} 

, если вы хотите, чтобы подавить сообщения из вашей программы, нужно перенаправить STDOUT, STDERR до запуска программы с системой().

Или используйте что-то наподобие IPC::System::Simple Или IPC :: Open3 (в основе).

0

У меня была такая же проблема, и выяснилось, что perl не был установлен. Таким образом, скрипт bash пытался выполнить perl без интерпретатора.

ls /usr/bin/perl