ご指摘ありがとうございます。おっしゃる通りですね。エイリアスファイルのデータフォークに書かれているのは、alis データではなくて、bookmark データでした。データフォークに alis を書くと、bookmark を期待しているプログラムで問題が起こる可能性が高いです。
ところで、NSURL のメソッドや CFURL の関数を使えば、最小限の bookmark を作れますが、残念ながら、この最小限の bookmark は、エイリアスファイルに書き出せません。一方で、エイリアスファイルに書き出せるように bookmark を作ると、アイコンデータが含まれてしまいます。どうやら、なんとしてもアイコンデータを埋め込ませたいらしい。
というわけで、肥大化したエイリアスファイルのデータフォークの処遇としては、そのまま放っておくか、削除するかのどちらかしかなく、アイコンをなくして小さくするというオプションはないようなので、スクリプトをそのように修正しました。現状ではデータフォークを削除するようにしてあります。なお、データフォークをそのまま残す選択をすると、エイリアスファイルのサイズは半分程度にしかできません。
それと、データフォークを削除する場合は、カスタムアイコンビットもクリアするようにしておきました。カスタムアイコンなんて久しく使わないので、すっかり忘れていた。(正確には、データフォークを削除しない場合でも、データフォークに bookmark データがないときは、カスタムアイコンビットをクリアすべきですが、bookmark の有無のチェックが面倒なので、 あると仮定してカスタムアイコンビットはそのままにしてあります。)
# US のボードでは、最近は主に rubycocoa で遊ばせてもらっています。何かのお役に立っているとすれば光栄です。でも、それももうすぐ終わりかもしれません。どうやら OSX 10.10 では、ruby 1.8 が丸ごとなくなっているらしく、つまり rubycocoa も標準では動かなくなるようです。朗報は、rubycocoa 1.2.0 がついに、ruby 2.0 以降に対応したことです。これで、志ある者は、最新版の rubycocoa をインストールしさえすれば、これまでどおり rubycocoa の恩恵に与れるはずなのですが、いかんせん、サポートサイトで質問に答えるのに、いちいちあれこれインストールしてくれと云うのも面倒かなと思う今日この頃です。
以下、修正版です。
#!/bin/bash /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby -w <<'EOF' - "$@" # # slim alias v0.33 # written by Hiroto, 2014-09 # # # ARGV = <file or directory> [<file or directory> ...] # require 'osx/cocoa' include OSX CLEAR_DATA_FORK = true # true to clear data fork which may contain bookmark data, false otherwise. while File.exist?(TEMPFILE = "/tmp/slim_alias.#{rand(1e6)}.r") do end Signal.trap("EXIT") { File.delete TEMPFILE if File.exist? TEMPFILE } def quoted_form(s) # # string s : source string # return string : s's quoted form for use in shell # * e.g., given s = a'b, quoted form of s = 'a'\''b' # %q['%s'] % s.gsub(/'/) {%q['\'']} end def slim_alias1(f) # # string f : POSIX path of alias file # * put 'alis' in resource fork, preserving data fork which may contain bookmark data # f = quoted_form(f) %x[ exec 2>/dev/null /usr/bin/derez -only 'alis' #{f} > "#{TEMPFILE}" || # derez 'alis' in resource fork exit # or exit /usr/bin/rez -o #{f} -noResolve output "#{TEMPFILE}" # put 'alis' in resource fork (overwrite resource fork) ] end def slim_alias2(f) # # string f : POSIX path of alias file # * put 'alis' in resource fork, clear data fork and clear custom icon bit # f = quoted_form(f) %x[ exec 2>/dev/null /usr/bin/derez -only 'alis' #{f} > "#{TEMPFILE}" || # derez 'alis' in resource fork exit # or exit /usr/bin/rez -o #{f} -noResolve output "#{TEMPFILE}" && # put 'alis' in resource fork (overwrite resource fork) : > #{f} && # and clear data fork /usr/bin/SetFile -a c #{f} # and clear custom icon bit ] end def scan_aliases(p) # # string p : absolute POSIX path of directory or file # return array : aliases in directory tree rooted at p if p is directory; [p] if p is alias file; otherwise [] # aa = [] ws = NSWorkspace.sharedWorkspace uti = ws.typeOfFile_error(p, nil) if uti == 'public.folder' de = NSFileManager.defaultManager.enumeratorAtPath(p) while (n = de.nextObject) != nil do f = p + '/' + n.to_s de.skipDescendants if ws.isFilePackageAtPath(f) # ignore package contents if de.fileAttributes.objectForKey(NSFileType) == NSFileTypeRegular aa << f if ws.typeOfFile_error(f, nil) == 'com.apple.alias-file' end end elsif uti == 'com.apple.alias-file' aa << p end aa end def main(argv) # # array argv : array of every target file or directory where target tree is rooted at # argv.map {|a| File.expand_path(a)}.each do |f| scan_aliases(f).each do |a| if CLEAR_DATA_FORK begin # skip if data fork == 0 and resource fork <= 4096 next if File.size(a) == 0 && File.size(a + '/..namedfork/rsrc') <= 4096 rescue end slim_alias2(a) else begin # skip if resource fork <= 4096 next if File.size(a + '/..namedfork/rsrc') <= 4096 rescue end slim_alias1(a) end end end end main(ARGV) EOF