はじめに
普段当たり前に使っていて気にもとめないcp
コマンドですが、今まで覚えていたことと違った出来事があったので記事に残しておきます。
一般ユーザ間のファイルコピー
同一サーバ内に存在する複数のユーザが同じファイルを触る要件があり、あるユーザからcp -p
でファイルをコピーしようとすると以下のようなエラーでコピーできませんでした。
> cp -p /home/user1/sharefile /var/tmp/sharefile
cp: `/var/tmp/sharefile' のタイムスタンプを保存中: 許可されていない操作です
自分の経験ではグループやパーミッション設定が問題なければコピーできるはずでしたが、まさか今更ファイルコピーでハマるとは・・・と思いながら調査すると、一般ユーザ間でコピーする場合、グループが同じでパーミッションも問題なかったとしても、オーナーの権限を書き換えられず、cp -p
等権限を保持したコピーをする場合、エラーでコピーできないとのこと。
ちなみにvi
等で直接編集したり、-p
オプション無しでコピーするような場合はオーナー権限は書き換わらないため、正常に終了します。
Solarisの場合
一般ユーザ間でcp -p
でコピーした場合、エラーでコピーできませんでしたが、大分昔に同じような要件のシステムがあり、その時はエラーが出るようなことは無かったはず・・・
どうにも腑に落ちず、以前よく使っていたSolaris
を準備し、同じことをやってみると、Solaris
ではエラーとならず、オーナー権限は書き換わらないままコピーできました。
動作についてきちんと理解できていなかったなぁと痛感しつつ、OSの違いを意識させられた出来事でした。
おわりに
後日、Solaris
のcp
コマンドのman
を見てみると、ちゃんと今回のことについても書かれていました。
ちゃんとマニュアルは読まないといけませんね。
-p 保持。cp ユーティリティーは、source_file の内容を複製するだけでは
なく、その ACL、アクセス日時と更新日時、拡張属性、拡張システム属
性、ファイルモード、および所有者 ID とグループ ID を保持しようと
します。
cp がアクセス日時と更新日時、拡張属性、またはファイルモードを保持
できない場合、cp はそれを失敗とは見なしません。cp が所有者 ID と
グループ ID を保持できない場合、コピーは失敗しませんが、cp はメッ
セージを表示せずにターゲットのファイルモードから S_ISUID および
S_ISGID ビットをクリアします。cp がこれらのビットをクリアできない
場合、コピーは失敗します。cp が ACL または拡張システム属性を保持
できない場合、コピーは失敗します。コピーが失敗すると、診断メッ
セージが stderr に書き込まれ、(残りのオペランドすべての処理後に)
cp がゼロ以外の終了ステータスで終了します。