Fed*_*nez 12 shell make hashsum
我开始使用org-mode在GTD风格的系统中规划我的任务。将每个 org 文件放在Dropbox文件夹的目录中,我运行 emacs 来编辑/管理来自三个不同本地机器的这些文件:Cygwin、Mac OS X 和 Debian。由于我还使用MobileOrg从我的 iPad 访问这些组织文件,因此checksums.dat
在进行任何更改时,文件必须保持最新。这可以通过运行来完成md5sum *.org > checksums.dat
。
问题是命令有三种不同的md5sum
命令:md5sum.exe
在 Cygwin、md5
Mac OS X 和md5sum
Debian 中。最理想的情况是生成文件,存储在 Dropbox 文件中,检测当前机器中可用的命令并运行该命令来执行 md5 校验和操作。
不幸的是,没有生成加密校验和的标准实用程序。有一个标准工具来生成一个CRC:cksum
; 这可能足以用于检测非敌对环境中的变化。
我建议使用 SHA1 而不是 MD5。有 MD5 实用程序但没有 SHA1 的系统并不多,如果您打算使用加密校验和,您不妨使用一种没有已知方法的算法来查找冲突(假设您还检查了大小)。
一种非标准但常见且可以计算摘要的工具是OpenSSL。它可用于 Cygwin、Debian 和 OSX,但不幸的是,它不是 OSX 上默认安装的一部分。
openssl dgst -sha1
Run Code Online (Sandbox Code Playgroud)
在 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
Run Code Online (Sandbox Code Playgroud)
您可以使用该shell
函数在加载生成文件时运行 shell 代码段并将输出存储在变量中。
sum := $(shell { command -v sha1sum || command -v sha1 || command -v shasum; } 2>/dev/null)
%.sum: %
$(sum) $< >$@
Run Code Online (Sandbox Code Playgroud)
您只能在规则中运行 shell 命令,因此计算校验和的每个规则都必须包含查找代码。您可以将代码片段放在一个变量中。请记住,规则中的单独行是独立评估的。还要记住,$
要传递给 shell 的符号需要转义为$$
.
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
Run Code Online (Sandbox Code Playgroud)
这有点像 hack,但是您可以测试每个是否存在并在它们存在时执行它们:
[ -x "`which md5 2>/dev/null`" ] && md5 newfile >>sums
[ -x "`which md5sum 2>/dev/null`" ] && md5sum newfile >>sums
Run Code Online (Sandbox Code Playgroud)
我很确定 cygwin 可以识别md5sum
不带 的命令(包括).exe
,但如果必须,请包括它。