2010/11/28

sedとperlで置換処理をするとファイルのownerが変更される

HTMLの置換処理をしていたときに,全ファイルのownerが変更されていたので気になって調べたのでメモ.

実行したコマンド

$ find . -type f -name "*.html" | xargs perl -i -pe 's/aaa/bbb/g'

perlをsedに置き換えても同様の現象が起きたので,内部で何が起きているのかstraceで確かめてみた

perlの場合

下記コマンドを実行して,perl-outの中身を確認

$ sudo strace -o perl-out perl -i -pe 's/aaa/bbb/' a.txt 
open("a.txt", O_RDONLY|O_LARGEFILE)     = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbf96cae8) = -1 ENOTTY (Inappropriate ioctl for device)
_llseek(3, 0, [0], SEEK_CUR)            = 0
fstat64(3, {st_mode=S_IFREG|0644, st_size=12, ...}) = 0
fcntl64(3, F_SETFD, FD_CLOEXEC)         = 0
unlink("a.txt")                         = 0
open("a.txt", O_WRONLY|O_CREAT|O_EXCL|O_LARGEFILE, 0600) = 4
ioctl(4, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbf96cae8) = -1 ENOTTY (Inappropriate ioctl for device)
_llseek(4, 0, [0], SEEK_CUR)            = 0
fstat64(4, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
fcntl64(4, F_SETFD, FD_CLOEXEC)         = 0
fstat64(4, {st_mode=S_IFREG|0600, st_size=0, ...}) = 0
fchmod(4, 0100644)                      = 0
fchown32(4, 1000, 1000)                 = 0
read(3, "ddd\nbbb\nccc\n", 4096)        = 12
read(3, "", 4096)                       = 0
write(4, "ddd\nbbb\nccc\n", 12)         = 12
close(4)                                = 0
close(3)                                = 0
exit_group(0)                           = ?
  1. a.txtをO_RDONLYでopen (fd=3)
  2. a.txtをunlink
  3. a.txtを今度はO_WRONLYでopen (fd=4)
  4. fd=3のa.txtからreadして,fd=4のa.txtに書き込み
  5. fd=4, fd=3をclose

2でunlinkして,同じ名前のファイルを再度作成しているのでownerがかわる模様

sedの場合

こんな感じのコマンドを実行して

$ sudo strace -e trace=open,close,rename,write,read -o sed-out sed -i 's/aaa/ddd/' a.txt

set-outに吐き出されたログを確認

open("a.txt", O_RDONLY|O_LARGEFILE)     = 3 
open("/proc/filesystems", O_RDONLY|O_LARGEFILE) = 4 
read(4, "nodev\tsysfs\nnodev\trootfs\nnodev\tb"..., 1024) = 337 
read(4, "", 1024)                       = 0 
close(4)                                = 0 
open("./sedwfohhg", O_RDWR|O_CREAT|O_EXCL|O_LARGEFILE, 0600) = 4 
read(3, "ddd\nbbb\nccc\n", 4096)        = 12
write(4, "ddd\n", 4)                    = 4 
write(4, "bbb\n", 4)                    = 4 
write(4, "ccc\n", 4)                    = 4 
read(3, "", 4096)                       = 0 
close(3)                                = 0 
close(4)                                = 0 
rename("./sedwfohhg", "a.txt")          = 0 
close(1)                                = 0 
close(2)                                = 0 
  1. a.txtをopen
  2. 一時ファイルとして./sedwfohhgをopen
  3. a.txtをreadして,中身を./sedwfohhgにwrite
  4. a.txtをclose
  5. ./sedwfohhgをa.txtにrename

renameしちゃっているのでownerが変わることになる

0 件のコメント:

コメントを投稿