makefileは、コマンドがローカルマシンで使用できるかどうかをどのように検出できますか?


11

GTDスタイルのシステムでタスクを計画するために、org-modeを使い始めました。Dropboxフォルダーのディレクトリにすべての組織ファイルを置き、emacsを実行して、Cygwin、Mac OS X、Debianの3つの異なるローカルマシンからこれらのファイルを編集/管理します。私はMobileOrgを使用してiPadからこれらの組織ファイルにアクセスするので、変更が行われたときはファイルを最新の状態に保つ必要があります。これを実行するには、を実行します。checksums.datmd5sum *.org > checksums.dat

問題は、コマンドに対して3つの異なるコマンドがあることですmd5summd5sum.exeCygwin、md5Mac OS X、およびmd5sumDebianです。最も理想的な状況は、Dropbox foderに保存されているmakefileで、現在のマシンで使用可能なコマンドを検出し、そのコマンドを実行してmd5チェックサム操作を実行します。



1
@ケビンそれはやり過ぎのようですね。3つの異なるシステムにプログラムをインストールしたくありません。各システムでは、Dropboxフォルダーにローカルディレクトリとしてアクセスできます。make checksumDropboxフォルダーの下でチェックサムデータを生成するために実行すると、現在のマシンで使用可能なチェックサムコマンドを検出した後、makefileが適切なコマンドを使用するようにします。
Federico Magallanez、2012年

大量のスクリプトを作成する予定で、プロジェクトが小さい場合は、sconsをお勧めします。
Faheem Mitha、2012年

回答:


7

チェックサムを生成するための可能なコマンド

残念ながら、暗号化チェックサムを生成する標準のユーティリティはありません。CRCを生成する標準ユーティリティがありcksumます。これは、非悪意のある環境での変更を検出する目的にとって十分な場合があります。

MD5ではなくSHA1を使用することをお勧めします。MD5ユーティリティはあるがSHA1がないシステムは多くありません。暗号化チェックサムを使用する場合は、既知の方法がないアルゴリズムを使用して衝突を見つけることもできます(サイズもチェックする場合)。

標準ではないが一般的であり、ダイジェストを計算できるツールの1つがOpenSSLです。Cygwin、Debian、OSXで利用できますが、残念ながらOSXのデフォルトインストールには含まれていません。

openssl dgst -sha1

OSX 10.6には、shasumDebian(perlパッケージの一部)にも存在するユーティリティがあり、Cygwinも信じています。これはPerlスクリプトです。ほとんどのUNIXシステムにはPerlがインストールされているため、このスクリプトがどこでも利用できないのではないかと心配な場合は、メイクファイルと一緒にそのスクリプトをバンドルできます。

システムに適したコマンドを選択する

さて、どこでも機能するコマンドが本当に見つからないとしましょう。

シェルで

使用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関数を使用して、メイクファイルがロードされたときにシェルスニペットを実行し、出力を変数に格納できます。

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

ポータブル(POSIX)make

ルールではシェルコマンドしか実行できないため、チェックサムを計算する各ルールにはルックアップコードを含める必要があります。スニペットを変数に入れることができます。ルールの個別の行は独立して評価されることに注意してください。また$、シェルに渡される標識はにエスケープする必要があることを覚えておいてください$$

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

上記の「GNU make」メソッドを適切に機能させるために-Ptypeコマンドのオプションを使用する必要があったため、最終的にはになりましたsum := $(shell { type -P sha1sum || type -P sha1 || type -P shasum; } 2>/dev/null)
ショーン

@Seanバグレポートをありがとう。type -Pシェルがbashの場合にのみ機能します。たとえば、kshやダッシュ(Ubuntuの場合など)の場合は機能しません。あなたは使用することができcommand -v、移植のために。
Gilles「SO-邪悪なことをやめなさい」2015

typeからに切り替えたようですcommand。他の方法も更新する必要がありますか?
Sean

@Sean他の方法は問題ありません。typeコマンドの存在をテストするための正しいポータブルな方法です。問題はsha1sum is /usr/bin/sha1sum、プログラム名だけでなく、次のような出力が生成されることです。これは、type単なる戻り値ではなく、出力を使用した唯一の場所でした。
Gilles「SO-邪悪なことをやめなさい」2015

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を使用してテストは無意味ですので、唯一、とにかく実行ファイルを探します。
Chris Down、

"type"の使用に関する詳細:cmd = $(foo md5 md5sum barのcmdの場合は、$ cmd> / dev / null 2>&1 && echo $ cmd && break; done); $ CMDファイル1ファイル2ファイル3> md5.txt
マイケル


1

どちらの GNUのautotoolsの(コメントで述べたように)、あるいはまた、CMakeのはオプションです。

GNU autotoolsはより伝統的なアプローチですが、(そしておそらく自分のためだけに言えば)最初にそれらを使用してプロジェクトをセットアップするという見通しに人々がそれほど興奮しているとは思いません。まあ、いずれにしても、それは学習曲線です。CMakeはブロックの新しい子供で、おそらくあまり一般的ではありません(まだ学習曲線があります)。独自の構文があり、プラットフォーム用のメイクファイルを生成します。CMakeには、それほど* x中心ではないという明確な利点があります。unix、windows、macでも確実に動作します(たとえば、makefileの代わりにmsvcプロジェクトを生成できます)。

編集:そしてもちろん「メイクファイル」が提案されたので、この答えはその推測に沿っています。しかし、おそらくpythonスクリプトまたは(gasp)単純なJavaプログラムだけがこのタスクに適しています。スクリプト/プログラミング言語は、これをプラットフォーム間で同じようにします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.