Как я запускаю скрипт Perl из сценария Perl?

Предупреждение: [fункция] : не удалось открыть поток: [причина]

Это происходит, когда вы обычно вызываете файл include , require или fopen, и PHP не смог найти файл или не имел достаточного разрешения на загрузку файла.

Это может произойти по разным причинам:

  • неправильный путь к файлу
  • путь к файлу относительный
  • include path is wrong
  • разрешения слишком ограничительные
  • SELinux в силе
  • и многие другие ...

Одна из распространенных ошибок заключается в том, чтобы не использовать абсолютный путь. Это можно легко решить, используя полный путь или магические константы , такие как __DIR__ или dirname(__FILE__):

include __DIR__ . '/inc/globals.inc.php';

или:

require dirname(__FILE__) . '/inc/globals.inc.php';

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

Лучший способ для быстрого решения этой проблемы необходимо выполнить контрольный список устранения неполадок ниже.

Вопросы, относящиеся:

Связанные ошибки:

25
задан Community 23 May 2017 в 10:29
поделиться

8 ответов

Местоположение Вашего текущего интерпретатора жемчуга может быть найдено в специальной переменной $^X. Это важно, если жемчуг не находится в Вашем пути, или если Вы имеете несколько версий жемчуга в наличии, но чтобы удостовериться, что Вы используете того же через плату.

При выполнении внешних команд, включая другие программы Perl, определении, работали ли они на самом деле, может быть довольно трудным. Осмотр $? может оставить длительные умственные шрамы, таким образом, я предпочитаю использовать IPC:: Система:: Простой (доступный от CPAN):

use strict;
use warnings;
use IPC::System::Simple qw(system capture);

# Run a command, wait until it finishes, and make sure it works.
# Output from this program goes directly to STDOUT, and it can take input
# from your STDIN if required.
system($^X, "yourscript.pl", @ARGS);

# Run a command, wait until it finishes, and make sure it works.
# The output of this command is captured into $results.
my $results = capture($^X, "yourscript.pl", @ARGS);

В обоих из вышеупомянутых примеров любые аргументы, которые Вы хотите передать своей внешней программе, входят @ARGS. Оболочки также избегают в обоих из вышеупомянутых примеров, который дает Вам небольшое преимущество скорости и избегает любых нежелательных взаимодействий, включающих метасимволы оболочки. Вышеупомянутый код также ожидает, что Ваша вторая программа возвратит нулевое значение выхода для указания на успех; если это не так можно определить дополнительный первый аргумент допустимых значений выхода:

 # Both of these commands allow an exit value of 0, 1 or 2 to be considered
 # a successful execution of the command.

 system( [0,1,2], $^X, "yourscript.pl", @ARGS );
 # OR
 capture( [0,1,2, $^X, "yourscript.pl", @ARGS );

, Если у Вас есть продолжительный процесс и Вы хотите обработать его данные , в то время как он сгенерирован, тогда Вы, вероятно, собираетесь нуждаться в переданном по каналу открытом, или один из более тяжелых модулей IPC от CPAN.

сказавший все это, любое время необходимо называть другую программу Perl от Perl, можно хотеть рассмотреть, если использование модуля было бы лучшим выбором. Запуск другой программы несет довольно много издержек, и с точки зрения затрат на запуск и с точки зрения затрат ввода-вывода для движущихся данных между процессами. Это также значительно увеличивает трудность обработки ошибок. Если можно превратить внешнюю программу в модуль, можно найти, что она упрощает общий замысел.

Всего самого лучшего,

Paul

31
ответ дан pjf 28 November 2019 в 17:41
поделиться

Вы можете всего делать это.

{
    local @ARGV = qw<param1 param2 param3>;
    do '/home/buddy/myscript.pl';
}

Предотвращает издержки загрузки в другой копии жемчуга.

32
ответ дан Axeman 28 November 2019 в 17:41
поделиться

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

12
ответ дан innaM 28 November 2019 в 17:41
поделиться

Используйте обратные галочки, если необходимо получить вывод команды.

Использование system, если Вы не должны получать вывод команды.

TMTOWTDI: таким образом, существуют другие пути также, но те - два, самые легкие и наиболее вероятные.

6
ответ дан Jonathan Leffler 28 November 2019 в 17:41
поделиться

Я могу думать о нескольких способах сделать это. Вы уже упомянули первые два, таким образом, я не буду вдаваться в подробности о них.

  1. обратные галочки: $retVal = ''perl somePerlScript.pl;
  2. система () вызов
  3. оценка

оценка может быть выполнена путем прихлебывания другого файла в строку (или список строк), тогда 'eval'ing строки. Вот образец:

#!/usr/bin/perl
open PERLFILE, "<somePerlScript.pl";
undef $/;   # this allows me to slurp the file, ignoring newlines
my $program = <PERLFILE>;
eval $program;

4. сделайте:

do 'somePerlScript.pl'
11
ответ дан smonff 28 November 2019 в 17:41
поделиться

Посмотрите документация perlipc для нескольких опций для межпроцессного взаимодействия.

, Если Ваш первый сценарий просто настраивает среду для второго сценария, можно искать exec.

5
ответ дан brian d foy 28 November 2019 в 17:41
поделиться

Если необходимо асинхронно назвать внешний сценарий - Вы просто хотите запустить его и не ожидать его для окончания - то:

# On Unix systems, either of these will execute and just carry-on
# You can't collect output that way
`myscript.pl &`;
system ('myscript.pl &');    

# On Windows systems the equivalent would be
`start myscript.pl`;
system ('start myscript.pl');

# If you just want to execute another script and terminate the current one
exec ('myscript.pl');
6
ответ дан Renaud Bompuis 28 November 2019 в 17:41
поделиться
#!/usr/bin/perl
use strict;

open(OUTPUT, "date|") or die "Failed to create process: $!\n";

while (<OUTPUT>)
{
  print;
}

close(OUTPUT);

print "Process exited with value " . ($? >> 8) . "\n";

Это запустит процесс date и передаст вывод по каналу команды к ВЫХОДНОМУ дескриптору файла, который можно обработать строку за один раз. Когда команда закончена, можно закрыть выходной дескриптор файла и получить возвращаемое значение процесса. Замена date с тем, что Вы хотите.

1
ответ дан Robert Gamble 28 November 2019 в 17:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: