他ユーザと共有しているファイルのコピー


はじめに

あるファイルを上書きコピーするときにエラーが表示され、少しハマったので書き残します。

発生した問題

ユーザAとユーザBが同サーバ上の共有ディレクトリに同じファイル名のファイルを上書きコピーする際にエラーとなりました。

ユーザA、ユーザBともに同じグループに所属しており、ファイル、ディレクトリのパーミッションは777となっているため、権限自体は問題なし。
※実際とは若干異なりますが説明を簡単にするために書き換えています。

原因

分かってしまえば単純な話で、一般ユーザは他ユーザが所有しているファイル等に対して上書きするとき、所有者の情報を書き換えられないことが原因でした。

以下、ユーザAが所有者のファイルに対してユーザBが上書きコピーした際のエラー。

userBのsharefileを/shareにコピーしたときのエラー
[userB@Server ~]$ cp -p /home/userB/sharefile /share/sharefile
cp: `/share/sharefile' のタイムスタンプを保存中: 許可されていない操作です

タイムスタンプと書かれていたため、変更日時が変えられないと思っていましたが、所有者、グループ等の情報もタイムスタンプに含まれるということに行きつくまでに時間を取られてしまいました・・・

尚、-pオプション無しでコピーした場合や、vi等でファイルを直接編集した場合は、所有者、グループ情報はコピーされないため、問題なく成功します。

ちなみに後から調べてみたところ、エラーは表示されますが、ファイルのコピー自体は行われているようです。

WinSCPでのコピー

WindowsでサーバへSCPする際などによく使われるWinSCPですが、デフォルトでは-pオプションが有効となった設定となっているため、「オプション」→「環境設定」→「転送」から「デフォルト」プリセットの「編集」で「タイムスタンプを保存する」のチェックを外すか、「パーミッションエラーを無視する」のチェックを入れることで、今回のような場合でもエラーメッセージが表示されないようになります。

おわりに

自分の過去の記憶では、同じ方法でもエラーが出なかったはず・・・と思い返し、ふと気になって以前よく使っていたSolarisの仮想マシンを用意して試してみたところ、Solarisではエラー出力はされずにコピーされるようです。

以下Solariscpコマンドのman抜粋。

-p
保持。cp ユーティリティーは、source_file の内容を複製するだけではなく、その ACL、アクセス日時と更新日時、拡張属性、拡張システム属性、ファイルモード、および所有者 ID とグループ ID を保持しようとします。
cp がアクセス日時と更新日時、拡張属性、またはファイルモードを保持できない場合、cp はそれを失敗とは見なしません。
cp が所有者 ID とグループ ID を保持できない場合、コピーは失敗しませんが、cp はメッセージを表示せずにターゲットのファイルモードから S_ISUID およびS_ISGID ビットをクリアします。

使い慣れたコマンドでもマニュアルをしっかり読んで動作はきちんと覚えましょうというお話でした。