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が変わることになる

2010/11/21

Hokkaido.pm #3の感想

スタッフとスピーカー,参加者の皆様,お疲れ様でした.
初心者向けと銘打ったおかげか大変盛況で,今後もこれが続くとよいな思っております.

とりあえず箇条書きでざっくりと
  1. Perlのことを誰に聞けばいいかわからない
  2. Perl Mongerは怖そう 
  3. 初心者向けじゃないと来なかった
  4. 他の言語経験者向けの本ってあるのか
1~3は今後もHokkaido.pmの活動を続けていけば解決してくれるんじゃないかと楽観的に考えてます.

4はPerlクイックリファレンスが良さそうだけど,実際に中身を見たことがない.2000年に出版なんで今だとちょっと内容が古いんじゃなかろうか.
プログラミング初心者には初めてのPerlでいいだろうけど,他言語の経験者にはまどろっこしい気がして勧めづらい

後は私のトークで使ったスライド貼っておきます.