19195


rootが例えば下記のようなコマンドで、一般ユーザが所有するのファイルを一括置換したとしても、ファイル自体の所有者は変更されない、という考え方で合っているでしょうか？

[code]

    $ find /path -type f -exec sed -i 's%hoge%piyo%g' {} +
    
[/code]

**質問**

  * root の所有になるのは、root (`sudo -s` でスイッチ) が明示的に既存ファイルの所有者を変更したときか、root (`sudo -s` でスイッチ) が新規ファイルを生成 (もしくはダウンロード) した時だけでしょうか？
  * 編集は関係ない？

**質問背景**

  * 一般ユーザが所有するファイルを処理する際、`sudo -s` から一旦抜けて処理した方が良いのか、`sudo -s` のまま処理して良いのか分からないので


CC BY-SA 3.0
2015-11-23T06:46:33.547
19193
2015-11-24T03:40:32.427
2015-11-23T06:54:09.713
76
7886
question
unix
rootが一般ユーザのファイル内容を変更してもファイルの所有者は変更されない？


はい。所有者以外がファイルを書き換えた場合でも、その所有者が変更されることはありません。これはrootに限らずどのユーザでも同じです。


CC BY-SA 3.0
2015-11-23T06:50:31.740
19195
2015-11-23T16:38:47.203
2015-11-23T16:38:47.203
76
76
19193
answer


Unix系OSを前提とすると、APIのレベルの話では既存のファイルの「編集」ではownerが変わることはありません。

質問にあるように、アプリケーションの動作のレベルになると、どのように動くかはアプリケーションの実装次第で、同様の操作をしてもownerが変わる物があります。使用される個々のアプリケーションについて挙動を確認してください。


CC BY-SA 3.0
2015-11-24T00:39:35.683
19222
2015-11-24T00:39:35.683
5793
19193
answer


結論として、所有者は変更されません (少なくとも GNU sed の場合) が、少し補足を。

_(以降、「GNU sed」は、という言い回しをしていますが、これは、他は異なる、と言っているのではなく、他の sed
実装の挙動を知らないのでこのように限定しています)_

GNU sed の inplace
操作は、一時ファイルを出力し、それを既存ファイルと同じ名前にリネームする実装となっています。つまり、結果のファイルは元ファイルと異なるファイルとなります。異なるファイルになっていることは、
`sed -i` を行う前後で `ls -i` してみると i-node 番号が変化していることで分かります。  
このままでは、所有権が作業を行ったユーザーに、モードがデフォルトのものになってしまいますが、GNU sed
の場合は、新しく作成したファイルの所有権やモード、 ACL
等の情報を元ファイルに合わせる作業をわざわざ行っているため、単純に上書きした時のような動作となります。  
このような動作をするプログラムは GNU sed に限らず、例えば vim も同様の動作を行います。

また、所有権やモードについては Unix 系 OS の最初期からある概念なのでよいのですが、例えば、Linux の ACL や SELinux
の情報等は、それらに対応していない古い sed で inplace 処理を行うと失われてしまうことがあるので注意が必要です。


CC BY-SA 3.0
2015-11-24T02:33:10.817
19225
2015-11-24T02:33:10.817
7831
19193
answer


本題からは外れますが、GNU sed の in place 置換で気を付けなければならない点はシンボリックリンクファイルの扱いです。

[code]

    $ lsb_release -ir
    Distributor ID: Ubuntu
    Release:        15.10
    
    $ sed --version
    sed (GNU sed) 4.2.2
    
    $ echo 'Hello' > a
    $ ln -s a b
    $ ls -l
    -rw-r--r-- 1 nemo nemo  6 Nov 24 12:18 a
    lrwxrwxrwx 1 nemo nemo  1 Nov 24 12:18 b -> a
    
    $ sed -i 's/Hello/World/' b
    $ ls -l
    -rw-r--r-- 1 nemo nemo 6 Nov 24 12:18 a
    -rw-r--r-- 1 nemo nemo 6 Nov 24 12:18 b
    
[/code]

以上の様に、シンボリックリンクが解除されて新たに通常ファイルが作成されてしまいます。

この動作を防ぐためのオプションスイッチが用意されています。

> **sed(1)**
>
> \--follow-symlinks  
>  follow symlinks when processing in place
[code]

    $ rm -f b; ln -s a b
    $ sed -i --follow-symlinks 's/Hello/World/' b
    -rw-r--r-- 1 nemo nemo  6 Nov 24 12:20 a
    lrwxrwxrwx 1 nemo nemo  1 Nov 24 12:20 b -> a
    
[/code]

※ FreeBSD の sed コマンドでもシンボリックリンクは解除されますが、それを抑止するオプションは無さそうです


CC BY-SA 3.0
2015-11-24T03:40:32.427
19230
2015-11-24T03:40:32.427
19193
answer