bir makefile, yerel makinede bir komutun bulunup bulunmadığını nasıl tespit edebilir?


11

GTD tarzı sistemdeki görevlerimi planlamak için kuruluş modunu kullanmaya başladım . Her kuruluş dosyasını bir Dropbox klasörünün dizinine koyarak , bu dosyaları üç farklı yerel makineden düzenlemek / yönetmek için emacs çalıştırıyorum: Cygwin, Mac OS X ve Debian. Bu org dosyalarına iPad'imden erişmek için MobileOrg'u da kullandığım için , herhangi bir değişiklik yapıldığında dosyanın güncel tutulması gerekiyor. Bu koşarak yapılabilir .checksums.datmd5sum *.org > checksums.dat

Sorun, komut için üç farklı md5sumkomutun olmasıdır: md5sum.exeCygwin, md5Mac OS X ve md5sumDebian. En ideal durum, bir Dropbox foder içinde saklanan bir makefile, mevcut makinede hangi komutun mevcut olduğunu algılar ve md5 sağlama toplamı işlemini yapmak için bu komutu çalıştırır.



1
@Kevin Kulağa aşırı gelmek gibi geliyor. Üç ayrı sistemde bir program kurmak istemiyorum. Her sistemde, bir Dropbox klasörüne yerel dizin olarak erişilebilir. Bir make checksumDropbox klasörü altında sağlama toplamı verileri oluşturmak için çalıştırdığımda , makefile geçerli makinede hangi sağlama toplamı komutunu algıladıktan sonra uygun bir komut kullanmasını istiyorum.
Federico Magallanez

Eğer önemli miktarda komut dosyası yazacaksanız ve proje küçükse, scons öneririm.
Faheem Mitha

Yanıtlar:


7

Bir sağlama toplamı oluşturmak için olası komutlar

Ne yazık ki, kriptografik bir sağlama toplamı oluşturmak için standart bir yardımcı program yoktur. CRC oluşturmak için standart bir yardımcı program vardır cksum:; bu, düşmanca olmayan bir ortamdaki değişiklikleri tespit etmek için yeterli olabilir.

MD5 yerine SHA1 kullanmanızı tavsiye ederim. MD5 yardımcı programı olan ancak SHA1 olmayan birçok sistem yoktur ve şifreleme sağlama toplamları kullanacaksanız, çarpışmaları bulmak için bilinen bir yöntemi olmayan bir algoritma da kullanabilirsiniz (boyutu da kontrol ettiğiniz varsayılarak).

Standart fakat yaygın olmayan ve özet hesaplayabilen bir araç OpenSSL'dir . Cygwin, Debian ve OSX için kullanılabilir, ancak maalesef OSX'teki varsayılan kurulumun bir parçası değildir.

openssl dgst -sha1

OSX 10.6'da shasumDebian'da ( perlpaketin bir parçası ) da bulunan bir yardımcı program var ve ben de Cygwin'e inanıyorum. Bu bir Perl betiğidir. Çoğu unix sisteminde Perl yüklü olduğundan, bu komut dosyasının her yerde bulunmadığından endişe ediyorsanız, bu komut dosyasını makyaj dosyanızla birlikte paketleyebilirsiniz.

Sisteminiz için doğru komutu seçme

Tamam, diyelim ki gerçekten her yerde çalışan bir komut bulamıyorsunuz.

Kabukta

typeBir komutun mevcut olup olmadığını görmek için yerleşik olanı kullanın.

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 markası

Sen kullanabilirsiniz shellişlevi makefile yüklendiğinde bir kabuk pasajı çalıştırmak ve bir değişkende çıktı saklayın.

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

Taşınabilir (POSIX) markası

Kabuk komutlarını yalnızca kural olarak çalıştırabilirsiniz, böylece bir sağlama toplamını hesaplayan her kuralın arama kodunu içermesi gerekir. Parçacığı bir değişkene koyabilirsiniz. Kurallardaki ayrı satırların bağımsız olarak değerlendirildiğini unutmayın. Ayrıca unutmayın $kabuk ihtiyaca geçirilecek olan işaretler kaçan edilecek $$.

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

Yukarıda açıklanan "GNU yapmak" yöntemi düzgün çalışması -Piçin typekomut seçeneğini kullanmak zorunda kaldı , bu yüzden sona erdi sum := $(shell { type -P sha1sum || type -P sha1 || type -P shasum; } 2>/dev/null).
Sean

@ Hata raporu için teşekkürler. type -Psadece kabuğunuz bash ise çalışır, örneğin ksh veya dash ise (diğerlerinin yanı sıra Ubuntu için de geçerlidir). command -vTaşınabilirlik için kullanabilirsiniz .
Gilles 'SO- kötü olmayı kes

Kullanmakta geçtik görünür typekullanarak command. Diğer yöntemler de güncellenmeli mi?
Sean

@Sean Diğer yöntemler iyidir: typebir komutun varlığını test etmek için doğru, taşınabilir bir yoldur, bununla ilgili sorun sha1sum is /usr/bin/sha1sum, program adı yerine çıktı üretmesidir . Bu, typesadece dönüş değeri yerine çıktısını kullandığım tek yerdi .
Gilles 'SO- kötü olmayı kes

5

Bu bir şey hack, ama her birinin var olup olmadığını test edebilir ve eğer yaparlarsa onları yürütebilirsiniz:

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

Cygwin'in komutları (dahil md5sum) olmadan tanıdığından oldukça eminim .exe, ancak gerekiyorsa ekleyin.


4
whichçıkış değerleri taşınabilir değildir. typeBunun yerine kullanın (ve muhtemelen if; then; elifbirden fazla yürütülebilir dosyada sorun yaşamamak için kullanmak istersiniz ). whichve typeyine de yalnızca yürütülebilir dosyaları arayın, bu nedenle -x ile yaptığınız test anlamsızdır.
Chris Down

"type" kullanımı hakkında daha fazla bilgi: cmd = $ (foo md5 md5sum çubuğundaki cmd için; $ cmd> / dev / null 2> & 1 && echo $ cmd && break; done yazın); $ cmd dosya1 dosya2 dosya3> md5.txt
michael


1

Ya GNU otoklavları (bir yorumda belirtildiği gibi) ya da CMake bir seçenektir.

GNU otoklavları daha geleneksel bir yaklaşımdır, ancak (ve belki de sadece kendim için konuşursak) İnsanların bunları kullanarak bir proje kurma ihtimalinde gerçekten çok heyecanlandıklarını düşünmüyorum. Her durumda, bir öğrenme eğrisi. CMake bloktaki yeni çocuktur ve belki de daha az yaygındır (ve hala bir öğrenme eğrisi vardır). Kendi sözdizimine sahiptir ve platformunuz için makefiles oluşturur. CMake'in bu kadar tek merkezli olmama gibi belirgin bir avantajı vardır; unix, windows ve mac üzerinde de güvenilir bir şekilde çalışır (örneğin, makefiles yerine msvc projeleri üretebilir.)

Düzenleme: ve tabii ki 'makefiles' önerildiğinden, bu cevap bu varsayımla birlikte gider. Ama belki de sadece bir python betiği veya (gasp) basit bir Java programı bu görev için daha uygun olurdu; kodlama / programlama dili bunu platformlar arasında aynı şekilde yapar.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.