installコマンドと一部オプションについての覚え書き

Last modified: 2021-10-11

installコマンドはファイルをコピーするという意味ではcpと同様だが、インストール作業に特化している。

各種オプションについて

以下に書いているものはオプションの一部。

アクセス権

アクセス権(パーミッション)は-m [属性]で設定できる。

所有者/グループ情報はそれぞれ-o [所有者]-g [グループ]で変更できる(管理者権限が必要)。

一般ユーザ権限で自分以外のユーザやグループの所有者/所有グループを指定して実行してもinstall: '[対象の場所]' の所有権を変更できません: 許可されていない操作ですとなって処理に失敗する。

タイムスタンプ情報

最終更新(mtime)と最新アクセス(atime)の情報を保持する場合は-pオプションを付ける。

コピー時にデバッグ情報を削除してファイルサイズを減らす

OSネイティブな機械語実行形式ファイルのコピー時、不要なシンボル情報を削除するために-sオプションを付けることができる。

ディストリのパッケージを作成する場合にはこれは使用せずにデバッグ情報を保持した状態でパッケージ作成用の階層へのファイルの配置を完了し、後でパッケージシステムがこれを削除するという形がとられるため、このオプションが用いられることはない。

ディレクトリの作成

-dオプションを付けるとディレクトリを作成でき、mkdir -pのように、途中のディレクトリが存在しない場合でも作成してくれる。

-mオプションでアクセス権を設定した場合、同時に作成された親ディレクトリの属性は設定されない1ようだ。

-Dオプションについて

(まだ存在しない場所の)ディレクトリを作成しつつ、その中にデータをコピー(インストール)したいという場合がある。

そのときに、事前にコピー先のディレクトリを作成せずにコピーをすることができるのがinstallコマンドの-Dオプション。

これを使用すると、RPMパッケージの.specファイルなどにおいて手動でファイルをコピー(インストール)する操作を短く記述できるようになる場合がある。2

ここでは例として、新しいディレクトリ/opt/myapp-ver/bin/の中に、現在のディレクトリにあるmyapp.binをコピーするものとする。

作業は

# install -d /opt/myapp-ver/bin
# install -m 755 myapp.bin /opt/myapp-ver/bin/

のように、先にディレクトリを作成してからコピー操作を行うことになるが、これはinstallコマンドの-Dオプションを使うと

# install -D -m 755 myapp.bin /opt/myapp-ver/bin/myapp.bin

と書ける。

コピー後のファイル名がコピー前と同一なので、シェルの展開3を利用すると

# install -D -m 755 {,/opt/myapp-ver/bin/}myapp.bin

または

# install -D -m 755 {./,/opt/myapp-ver/bin/}myapp.bin

と更に短く書くことができる。4

コピーしたいファイルが現在のディレクトリにない場合でも同様に書けて、img/myapp.pngを新しいディレクトリ/opt/myapp-ver/icons/へコピーしたい場合

# install -d /opt/myapp-ver/icons
# install -p -m 644 img/myapp.png /opt/myapp-ver/icons/

のようになるが、これは

# install -D -p -m 644 img/myapp.png /opt/myapp-ver/icons/myapp.png

となるため、展開を使用すると

# install -D -p -m 644 {img/,/opt/myapp-ver/icons/}myapp.png

と書ける。

まとめると

install -D ([その他のオプション...]) {[コピーしたいファイルのディレクトリ部分]/,[コピー先のディレクトリ]/}[コピーしたいファイルの名前]

となる。

コピーしたいファイルが現在のディレクトリにある場合には.を当てはめれば5この形に合う。

もし、ファイル名を変えてインストールする場合は、元の書き方に-Dオプションを付けるだけで

(元の書き方)
# install -d /opt/myapp-ver
# install -m 755 myapp.bin /opt/myapp-ver/newname.bin

(install -Dを使った書き方)
# install -D -m 755 myapp.bin /opt/myapp-ver/newname.bin

のようになる。

複数ファイルコピー時には-Dオプションは使えない

-Dは、コピー後のファイル名を含めて指定する性質上、複数のファイルを、まとめて(存在しない)ディレクトリへコピーするという使い方ができない。

for文を使って各ファイルを-Dオプション付きで処理するということはできるが、かえって長くなるため、無理にこのオプションを付けようとはせず、ディレクトリを先に作成してからパターン指定をして一括でコピーするほうがよい。

下の例ではincludeディレクトリ内の*.hファイルを新しいディレクトリ/opt/myapp-ver/include/へコピーしているが、元の書き方が一番好ましい。

(元の書き方)
# install -d /opt/myapp-ver/include
# install -m 644 include/*.h /opt/myapp-ver/include/

(install -Dを使った書き方・非推奨)
# for f in include/*.h; do install -D -m 644 {$(dirname ${f})/,/opt/myapp-ver/include/}$(basename ${f}); done

(install -Dを使った書き方その2・非推奨)
# for f in include/*.h; do install -D -m 644 {${f%/*.h}/,/opt/myapp-ver/include/}$(basename ${f}); done

  1. install -d -m 700 a/b/c/d/eを実行した場合、途中のaからdまでのディレクトリは既定のアクセス権になる ↩︎

  2. Gentooのebuildではdobin,dosbin,domanなどがあるため、直接installを使用することはほとんどなくて楽に書ける・また、doinsを使用するとinstallコマンドを内部的に使用してインストール操作が行える ↩︎

  3. bash,tcsh,zshで動作することを確認したが、dashでは動作しない ↩︎

  4. 簡単な因数分解のようにファイル名部分を右にくくり出す感じとも言える ↩︎

  5. {./,[コピー先のディレクトリ]...} ↩︎