2009-08-17 4 views
2

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

if ($has_jar) { 
    system("jar -c $compressed_file $infile"); 
} 
elsif ($has_zip) { 
    system("zip -j $compressed_file $infile"); 
} 
else { 
    copy($infile, $compressed_file); 
} 

Где, если они не имеют либо из приложений сжатия, она будет просто скопировать файл в расположение сжатого файла без сжатия.

Моя липкая калитка здесь заключается в том, что я не совсем уверен, что лучший способ определить, есть ли у них банка или почтовый индекс. Похоже, я могу использовать exec() вместо system() и воспользоваться тем фактом, что он возвращается только в случае сбоя, но сценарий действительно делает несколько вещей после этого, Работа.

Мне также нужно, чтобы это было переносным решением, так как этот скрипт работает как на Windows, так и на разных дистрибутивах Unix. Заранее спасибо.

+1

будет ли он работать на перлы раньше, чем 5.10.0? –

+0

Да. Пробовали две разные машины и получили 5.8.4 и 5.8.0. – Morinar

ответ

2

Просмотреть мои multi-which.

+0

Ооо, мне это нравится. Относительно просто и легко интегрируется в мой существующий скрипт. Не имея ничего сумасшедшего, я, скорее всего, буду использовать это. – Morinar

+0

Просто реализовано это, и все работает точно так, как я хочу ... Я знаю, что это аналогичный ответ Павлу Нафану, но Синан предоставил очень хороший кусок кода для работы. Спасибо всем за решения, гораздо больше, чем я ожидал. – Morinar

+0

@Morinar Спасибо. –

1

Просмотрите каталоги, указанные в переменной среды PATH.

+0

Да, это сработало бы, хотя я определенно надеялся на что-то более «гладкое». – Morinar

+0

Нет ничего более гладкого. Либо вы пытаетесь запустить исполняемый файл, либо сообщить об ошибке или посмотреть, есть ли подходящий исполняемый файл в пути, попробуйте запустить его ** и ** сообщить о любых сбоях. –

2

Для систем на базе * NIX, это должно работать:

my $has_jar = `which jar` ne ''; 

Это потенциально может работать на Windows, а также, если вы включите which.

В качестве альтернативы, вы можете попробовать команду, предложенную this answer,

my $has_jar = `for %i in (jar.exe) do @echo. %~$PATH:i` ne ''; 

Это, скорее всего, не возвращает «», если он не находит, однако, но у меня нет Perl доступны на Windows, чтобы проверить его.

+0

Это определенно работает на системах * nix, но на самом деле у меня нет возможности включить их в установку Windows. Если бы это было так просто, я бы просто связал zip с приложением и не задавал этот вопрос в первую очередь. – Morinar

+0

В этом случае я добавил еще одно потенциальное, но непроверенное решение. –

1

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

+0

Хорошая идея, но это не совсем вариант из-за того, как мы исправляем клиентов и как они настраиваются. – Morinar

1

Как просто попробуйте запустить программу. Если он не может быть запущен, то вы знаете, что есть проблема.

1

Почему бы не использовать Archive::Zip package для сжатия, исключив необходимость в внешней программе?

+1

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

+0

Если вы уже требуете, чтобы у них были пакеты, отличные от по умолчанию, в чем проблема с требованием этого? –

4

Думаю, ваш лучший выбор File::Which.

+0

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

+6

Тогда вы могли бы просто «украсть» код. – innaM

+1

Моринар: вы можете связать его –

1

Есть несколько вещей, чтобы думать о том, если вы собираетесь сделать это:

  • Использование системы и Exec в виде списка, так что оболочка не получает шанс интерпретировать специальные символы.

  • Можете ли вы сохранить это как конфигурацию вместо того, чтобы помещать ее в код? Посмотрите, например, как CPAN.pm.

  • Откуда вы знаете, что используете то, что считаете нужным? Если кто-то делает троянский конь с тем же именем, ваша программа будет счастливо исполнить его?Обратите внимание, что использование PATH, как указано в Sinan's multi, которое все еще имеет эту проблему, поскольку оно зависит от пользователя, устанавливающего PATH.

+0

Это определенно хороший совет. Я изменил свои призывы к системе, чтобы использовать форму списка, поскольку я самостоятельно обнаружил одно и то же. Я действительно не могу хранить это в любой конфигурации, поскольку у нас просто нет механизма на месте, и нет, нет способа узнать, что я запускаю или нет. Хотя я согласен с тем, что это, вероятно, вызывает беспокойство, среда, в которой работает наше приложение, как правило, вполне контролируется и санитария, поэтому наличие троянца или аналогичных приложений на самом деле не вызывает беспокойства. – Morinar