Как найти путь к скрипту find2perl в Unix, используя bash или perl - PullRequest
2 голосов
/ 26 октября 2011

Нам (компании, в которой я работаю) необходимо запустить сценарий find2perl на более чем тысяче различных Unix-серверов разных типов (Linux, Solaris, HP-UX, AIX) и разных версий.

Единственное, что объединяет все серверы, это то, что на всех них установлена ​​хотя бы одна реализация perl. Однако не все системы настроены одинаково.

Найти местоположение perl достаточно просто с помощью команды which. Однако на 70% серверов фактический каталог, содержащий find2perl (папка bin в perl), отсутствует в переменной $PATH и не может быть расположен таким образом.

На некоторых серверах perl на самом деле является символической ссылкой, указывающей другое местоположение, и в этом случае я могу использовать ls -l и sed для извлечения цели ссылки, чтобы найти, где Perl фактически установлен.

Однако на других серверах это сложнее, так как кажется, что perl был скомпилирован в произвольном месте, а двоичный файл perl, присутствующий в / bin или / usr / bin (или там, где perl найден), не является символической ссылкой, но скорее полноценный исполняемый файл. В этом случае я подумал об использовании переменной @INC в perl, чтобы попытаться найти find2perl, но это кажется довольно излишним.

Каким был бы лучший / лучший / полностью защищенный метод (по возможности, с одной строкой), чтобы всегда получать местоположение find2perl в системе Unix?

Ответы [ 2 ]

3 голосов
/ 26 октября 2011

способов определения местоположения find2perl

Два способа, оба из которых зависят от установки perl, как он был настроен:

Config.pm

Его , вероятно, scriptdirexp от Config.pm.

$ perl -MConfig -E 'say $Config{scriptdirexp}'
/usr/bin

И действительно, вот где find2perl находится в моей системе. Вы можете use Config; в ваших perl-скриптах, что является его основным преимуществом перед следующим методом.

perl -V: varname

Согласно комментарию Яника Жируара, вы также можете использовать perl -V:scriptdirexp, чтобы получить его в формате, подходящем для передачи на eval в сценарии оболочки. На самом деле доступно несколько форматов (поэтому вам не нужно использовать, например, вырезать для его анализа):

OPTION                 OUTPUT (\n = actual newline)     NOTES
-V:scriptdirexp        scriptdirexp='/usr/bin';\n       full shell syntax, even if multiple -V options
-V:scriptdirexp:       scriptdirexp='/usr/bin'          trailing colon omits semicolon and newline 
-V::scriptdirexp       '/usr/bin'; \n                   extra leading colon omits var= part
-V::scriptdirexp:      '/usr/bin'                       you can combine them.

Полная документация находится на странице perlrun .

Способы внедрения find2perl

Если вы решите скопировать find2perl в соответствии с комментарием evil otto , вы можете сделать это, внедрив его в свой скрипт оболочки. Есть много способов. Если ни один из двух приведенных ниже способов не работает, то вы, безусловно, можете использовать shar (который имеет чрезвычайно длинную историю и, вероятно, совместим со всем).

Цитируемый здесь документ

Самый простой способ - если ваша оболочка поддерживает цитируемые здесь документы. Все они должны, так как требование POSIX :

#!/bin/sh
perl - -name 'foo' -mtime 2 -print <<'FIND2PERL'
#!/usr/bin/perl
    eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
      if $running_under_some_shell;
⋮
FIND2PERL

шестнадцатеричный дамп в не цитируемом здесь документе

Если некоторые из ваших оболочек не реализуют цитируемые здесь документы ( POSIX‽, что это! ), то вы должны защитить find2perl от расширения оболочки. Самый простой способ - сбросить его в шестнадцатеричном формате, поскольку 0–9 и a – f все защищены от расширения оболочки. Дамп легко выполняется с помощью xxd -p /usr/bin/find2perl, для чего требуется только xxd на одном компьютере. Чтобы прочитать дамп, вы можете использовать обычный perl:

#!/bin/sh
perl -n -e 'chomp; print pack("H*", $_)' <<HEX | perl - -name 'foo'
23212f7573722f62696e2f7065726c0a202020206576616c202765786563
202f7573722f62696e2f7065726c202d5320243020247b312b222440227d
⋮
HEX

Использование find2perl несколько раз

Естественно, что при любом подходе вы также можете записать find2perl во временный файл (например, если вам нужно вызывать его несколько раз). Вы также можете встроить его в функцию оболочки.

1 голос
/ 26 октября 2011
perl -lwe '$_ = $^X; s/perl$/find2perl/; -f or die qq($_ not -f); print'

Скопируйте исполняемый путь интерпретатора в аргумент доллара по умолчанию. Установите значение, предполагая, что find2perl находится в том же каталоге, что и сама perl. (Это указано только для UNIX, поэтому вам не нужно обслуживать perl.exe, с которым было бы легко справиться.) Затем проверьте файл, существует die, если нет. (Вы можете придумать лучшую обработку ошибок.) Затем выведите путь, если мы еще живы. Вот и все.

Хорошо, вот версия, которая работает и для Windows:

perl -lwe "$_ = $^X; s/perl(\.exe)?$/find2perl/;
  -f or -f qq($_.bat) or die qq($_ not -f); print"

Обратите внимание на двойные кавычки, de rigueur на Windows для cmd.exe. И это должно идти в одну строку, я просто обернул его для удобства чтения.

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