як makefile може виявити, чи є команда доступною в локальній машині?


11

Я почав використовувати org-режим для планування своїх завдань в системі GTD -style. Поміщаючи всі org файли в каталог папки Dropbox , я запускаю emacs для редагування / управління цими файлами з трьох різних локальних машин: Cygwin, Mac OS X та Debian. Оскільки я також використовую MobileOrg для доступу до цих файлів org із свого iPad, checksums.datфайл повинен бути оновлений після будь-яких змін. Це можна зробити, запустивши md5sum *.org > checksums.dat.

Проблема полягає в тому, що для команд існують три різні команди md5sum: md5sum.exeу Cygwin, md5у Mac OS X та md5sumDebian. Найідеальніша ситуація - це makefile, який зберігається у Foder Dropbox, визначає, яка команда доступна в поточній машині, і виконує цю команду для виконання контрольної суми md5.



1
@Kevin Це звучить як надмір. Я не хочу встановлювати програму в трьох різних системах. У кожній системі папка Dropbox доступна як локальний каталог. Коли я запускаю make checksumдля генерації даних контрольної суми в папці Dropbox, я хочу, щоб makefile використовував відповідну команду після виявлення, яка команда контрольної суми доступна в поточній машині.
Федеріко Магальянес

Якщо ви збираєтеся зробити значну кількість сценаріїв, а проект невеликий, я б запропонував розцінки.
Faheem Mitha

Відповіді:


7

Можливі команди для генерації контрольної суми

На жаль, не існує стандартної утиліти для створення криптографічної контрольної суми. Існує стандартна утиліта для генерації CRC: cksum; це може бути достатньо для ваших цілей виявлення змін у неприязному середовищі.

Я рекомендую використовувати SHA1, а не MD5. Існує не так багато систем, у яких є утиліта MD5, але немає SHA1, і якщо ви збираєтеся використовувати криптографічні контрольні суми, ви також можете використовувати алгоритм без відомих методів пошуку зіткнень (якщо ви також перевірите розмір).

Один інструмент, який не є стандартним, але поширеним і може обчислювати дайджести, - OpenSSL . Він доступний для Cygwin, Debian та OSX, але, на жаль, не є частиною встановлення за замовчуванням на OSX.

openssl dgst -sha1

На OSX 10.6 є shasumутиліта, яка також присутня на Debian (це частина perlпакета), і я вірю і в Cygwin. Це сценарій Perl. У більшості систем Unix встановлено Perl, тому ви можете поєднати цей скрипт поряд із вашим makefile, якщо ви переживаєте, що цей сценарій недоступний скрізь.

Вибір правильної команди для вашої системи

Добре, скажімо, ви дійсно не можете знайти команду, яка працює скрізь.

В оболонці

Використовуйте typeвбудований, щоб побачити, чи є команда.

sum=
for x in sha1sum sha1 shasum 'openssl dgst -sha1'; do
  if type "${x%% *}" >/dev/null 2>/dev/null; then sum=$x; break; fi
done
if [ -z "$sum" ]; then echo 1>&2 "Unable to find a SHA1 utility"; exit 2; fi
$sum *.org

GNU make

Ви можете використовувати shellфункцію для запуску фрагмента оболонки під час завантаження makefile та зберігання результатів у змінній.

sum := $(shell { command -v sha1sum || command -v sha1 || command -v shasum; } 2>/dev/null)
%.sum: %
        $(sum) $< >$@

Портативний (POSIX) марка

Ви можете запускати тільки команди оболонки в правилі, тому кожне правило, що обчислює контрольну суму, повинно містити код пошуку. Ви можете помістити фрагмент у змінну. Пам'ятайте, що окремі рядки в правилах оцінюються незалежно. Також пам’ятайте, що $знаки, які мають бути передані оболонці, потрібно уникати $$.

determine_sum = \
        sum=; \
        for x in sha1sum sha1 shasum 'openssl dgst -sha1'; do \
          if type "$${x%% *}" >/dev/null 2>/dev/null; then sum=$$x; break; fi; \
        done; \
        if [ -z "$$sum" ]; then echo 1>&2 "Unable to find a SHA1 utility"; exit 2; fi

checksums.dat: FORCE
    $(determine_sum); \
    $$sum *.org

Мені довелося скористатися -Pпараметром typeкоманди, щоб змусити описаний вище метод "GNU make" працювати належним чином, тому я закінчив sum := $(shell { type -P sha1sum || type -P sha1 || type -P shasum; } 2>/dev/null).
Шон

@ Дякую за повідомлення про помилку. type -Pпрацює лише якщо ваша оболонка є bash, не якщо це, наприклад, ksh або dash (що стосується Ubuntu серед інших). Ви можете використовувати command -vдля портативності.
Жил "ТАК - перестань бути злим"

Здається, ви перейшли з використання typeна використання command. Чи варто також оновлювати інші методи?
Шон

@Sean Інші методи прекрасні: typeце правильний, портативний спосіб перевірити наявність команди, проблема з цим полягає в тому, що вона дає вихід, sha1sum is /usr/bin/sha1sumа не просто ім'я програми. Це було єдине місце, де я використовував вихід, typeа не просто його повернене значення.
Жил "ТАК - перестань бути злим"

5

Це щось злому, але ви можете перевірити, чи існує кожен, і виконати їх, якщо вони:

[ -x "`which md5 2>/dev/null`" ] && md5 newfile >>sums
[ -x "`which md5sum 2>/dev/null`" ] && md5sum newfile >>sums

Я впевнений, що cygwin розпізнає команди (в тому числі md5sum) без значень .exe, але включати їх, якщо потрібно.


4
whichзначення виходу не є портативними. Використовуйте typeнатомість (і ви, мабуть, хочете скористатися, if; then; elifщоб уникнути проблем у наявності кількох виконуваних файлів) whichі typeшукайте лише виконувані файли в будь-якому випадку, тому ваш тест з -x є безглуздим.
Кріс Даун

більше про використання "type": cmd = $ (для cmd у foo md5 md5sum bar; введіть $ cmd> / dev / null 2> & 1 && echo $ cmd && break; done); $ cmd file1 file2 file3> md5.txt
michael


1

Або автоінструменти GNU (як зазначено в коментарі), або також CMake - це варіант.

Автоінструменти GNU - це більш традиційний підхід, але (і, мабуть, кажучи лише для себе), я не думаю, що люди насправді дуже схвильовані перспективою спочатку створити проект, використовуючи їх. Ну, це крива навчання, в будь-якому випадку. CMake - це найновіша дитина, яка, можливо, є менш поширеною (і все ще має криву навчання). У нього є власний синтаксис, і він створює файли для вашої платформи. CMake має виразну перевагу бути не настільки un * x -центричним; він надійно працює і в unix, windows та mac (наприклад, він може генерувати msvc проекти, наприклад, замість makefiles.)

Редагувати: і, звичайно, оскільки пропонували «макіяжі», ця відповідь відповідає цій презумпції. Але, можливо, для цього завдання більш доречним буде лише сценарій python або (задихана) проста програма Java; мова сценаріїв / програмування зробить це так само на всіх платформах.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.