ユーザー権限で必要なパッケージをローカルインストールするまとめスクリプト の中で Stow を使ってパッケージを管理インストールしてましたが、 ちょっとStowには問題があってそれを中で無理やり解決していました。
その辺を XStow というStowの代替コマンドが上手く処理してくれるようなのでそちらを 試してみました。
Stowの問題点
Stowを使うときは、まず、configure
コマンドなどで、
~/usr/local/stow/screen-4.2.1/
等の様にstowというディレクトリの下の
パッケージの名前を付けたディレクトリを指定して
各パッケージをインストールします。
その後、stowディレクトリで
$ stow screen-4.2.1
等とすると、stow/screen-4.2.1/bin/screen等へのリンクが bin/screenなどへ貼られます。
この際、ディレクトリは、もし他のパッケージと共通するものがない場合、 ディレクトリ単位でリンクが貼られます。
上のbin/screenの場合も、一番最初にインストールするときなどは binへのリンクが貼られるだけです。
その後、他のパッケージがbinを使う時には、 リンクが一旦消されディレクトリが作られ、 その中に今度は中身のリンクが作られます。
この様に、ディレクトリ単位では同じ物があっても勿論良いわけですが、 一方、ファイルの同じ物がある場合は競合してインストールに失敗します。
これが良く起こるのがshare/info/dirというファイルです。
このファイルはinfo
コマンド等で見れる情報を読み取るのに使われるものですが、
各パッケージこの同じdirを使います。
make install
する際には、その辺、もしdirがあると良しなに
マージしてくれるみたいですが1、
Stowでは単にファイルを見てるだけなのでそのような事は出来ません。
そこで、前回のスクリプトの中では、 特にこのdirは要らないだろう、ということで
1 2 3 4 5 6 7 8 9 10 11 |
|
こんな感じのラッパー関数を書いて、新しくインストールするパッケージに
dirがあったら古いものを削除する、みたいな事をしていました。
(これだと後でまたstow
しようとすると競合が起こるので、いっそ
rm -f $1/share/info/dir
とパッケージ内の物を消してしまっても良いかもしれません、 まずdirの情報なんて使わない、というのであれば。)
以前手動でやってた時も良くこの問題が起きて 取り敢えず手で消して、みたいなことをしていました。
追記: 2015/04/22
コメントを貰いましたが、stow
には--ignore=REGREP
オプションを使って
特定をファイルを無視する事が出来ます。
このREGREP
はperlな正規表現を使って指定します。
上の問題のファイルだけを無視したいなら
stow --ignore='share/info/dir' <package>
の様な形。
さらにstow
には--defer
、--override
というオプションもあって、
れらは他のパッケージの中に指定したファイルがある場合に限り
それぞれ、無視、または上書きします2。
もし複数のファイルやディレクトリを指定したい場合には、
--ignore=name1 --ignore=name2
みたいにそれぞれ指定してもよいし、
perlな正規表現を使って--ignore='name1|name2'
みたいにも出来ます。
上のいちいち消してる作業は--override
と全く同じなのでこれで
そのまま代替出来ます。
下にXStowについて書きましたが、Stowの方はGNUパッケージで
よりいろんな所で配布されていてapt-get
とかでも取りやすいですし、
XStowはC++で書かれているので、ソースからコンパイルして入れる必要がある時、
g++とか入って無いといれなきゃいけなかったり
Stowよりはちょっt入れるのに大変かもしれません。
真面目にshare/info/dirの情報をマージしたい場合には
XStowを使うと便利ですが、
そうでない場合はStowで
--override='share/info/dir'
オプション付きで行うのが
良いです。
-D
で削除する際にこのオプションがあっても無くても
悪さはしないので
alias stow="stow --override='share/info/dir'"
みたいにstow
自体でエイリアスでオプションを与えてしまっても良いかもしれません。
追記ここまで
XStow
XStow はC++で書かれたStowの拡張版です。(StowはPerl。)
一応ページを見るとIt supports all features of Stow with some extensions.
と書いてあります。
ただ、これ、長い間開発が止まっていて、2010年から暫く更新がありませんでした。
上のdirの問題が起きた時なんかもこれを見つけたりしましたが、 どうも古いので使わないほうが良さそうだ、ということでStowの方を使ってました。
readline - Dealing with GNU Stow conflicts - Unix & Linux Stack Exchange
この問題はStowのToDoリスト には入れてある様です。
で、古いままだと思ってたら、昨年また更新されたようです。 Stowの方は2012年がリリース版の最終更新なので (GitHubのページ を見ると最近もちょこちょこ更新はしている様ですが) XStowのが新しいとうことになります。
ということで、使っても良いだろうとで使ってみることに。
ローカルインストールということで、
http://downloads.sourceforge.net/xstow/xstow-1.0.2.tar.bz2
からダウンロードしてインストールします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
取り敢えずインストールするディレクトリは~/usr/local/stowで。
後は、
$ xstow <package>
でインストール、
$ xstow -D <package>
でアンインストール、はStowと一緒です。
で、このままだとStowと同じ様に競合で失敗しますが、これを避けるには2つあって、 1つは
$ xstow -f <package>
とすることで、競合するファイルを無視することが出来ます。
もう一つは、上のStackExchangeにある方法で、 XStowの設定ファイル、xstow.iniに以下のような設定を書いておくことです。
[exec]
match = dir # GNU info index file
exec = merge-info %t %s -o %t
exec-unstow = merge-info -u %t %s -o %t
xstow.iniはホームディレクトリかstowでパッケージをインストールする ディレクトリに置いておきます。 (ホームディレクトリの場合は.xstow.iniと隠しファイルにしてもOK。)
設定ではdirというファイルがあった時、これを
merge-info
というコマンドでマージするようにする、と言うもの。
このmerge-info
もXStowの中に入っています。(xstow
と一緒にインストールされる。)
マージしようと思うとちょっと面倒なので、
取り敢えず今のところdirは要らないかな、ということで
-f
を使って回避するようにします。
前回のスクリプトをアップデートしたのがこちら。