|
2009/10/21 21:34
こんばんは。
皆様方、達者で暮しておりますでしょうか? 周りではインフルエンザで二人倒れたおじいさんです。
手洗いうがいはちゃんとやりましょうね。
さて、本題は、Perlのファイル周りです。なんか最近こんな事ばっかりしておりますが。
まあ、事の発端はCSVファイルを読み込んで更新したら、とある一行だけ吹っ飛んだ、ということなんですが。
で、怪しいのが
・print文で一行書き込みをミスった
・<FH>文で一行読み込みミスった
というぐらいしかないのですよ。
先日からprint文のPerlソースは追いかけていて、魔窟の中で苦労しているんですが、今度は読み込み側からおいかけているというところ。
で、今日ガーンというかなんというか、考えてみりゃあたりまえの話を再発見。
q.pl
#!/usr/bin/perl
open(FH,"<q.txt") or die;
while (<FH>) {
print ;
sleep 2;
}
q.txtはq.plと同じとしますね。
で、これをですね。sleepしている最中にぶっ壊すわけですよ。
[root@localhost perl]# strace perl q.pl
-bash: strace: command not found
[root@localhost perl]# perl q.pl &
[1] 29242
[root@localhost perl]# #!/usr/bin/perl
cp q.pl q.txtopen(FH,"<q.txt") or die;
cp: overwrite `q.txt'? ywhile (<FH>) {
es
[root@localhost perl]# print ;
sleep 2;
}
[1]+ Done perl q.pl
</blocquote>
あれ?最後まで動いた・・・まあ、これは先にファイル全体を読み込んでいるからなんでしょうけれどね。
その辺を確認するには、straceがよいです。
あれれ、straceはいってないやん。yumでインストール。
でもって、実行。
execve("/usr/bin/perl", ["perl", "q.pl"], [/* 23 vars */]) = 0
brk(0) = 0x885e000
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fee000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/tls/i686/sse2/libperl.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/tls/i686/sse2", 0xbfa703e8) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/tls/i686/libperl.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/tls/i686", 0xbfa703e8) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/tls/sse2/libperl.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/tls/sse2", 0xbfa703e8) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/tls/libperl.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/tls", 0xbfa703e8) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/i686/sse2/libperl.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/i686/sse2", 0xbfa703e8) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/i686/libperl.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/i686", 0xbfa703e8) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/sse2/libperl.so", O_RDONLY) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/sse2", 0xbfa703e8) = -1 ENOENT (No such file or directory)
open("/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/libperl.so", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\240q\231\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1241464, ...}) = 0
mmap2(0x977000, 1250976, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x977000
mmap2(0xaa2000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x12a) = 0xaa2000
mmap2(0xaa7000, 5792, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xaa7000
close(3) = 0
open("/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/libresolv.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=39391, ...}) = 0
mmap2(NULL, 39391, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7fe4000
close(3) = 0
open("/lib/libresolv.so.2", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\300\200v\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=76400, ...}) = 0
mmap2(0x766000, 75976, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x766000
mmap2(0x775000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xe) = 0x775000
mmap2(0x777000, 6344, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x777000
close(3) = 0
open("/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/libnsl.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/libnsl.so.1", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0 QW\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=101404, ...}) = 0
mmap2(0x572000, 92104, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x572000
mmap2(0x585000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x12) = 0x585000
mmap2(0x587000, 6088, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x587000
close(3) = 0
open("/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/libdl.so.2", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/libdl.so.2", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0PJ\224\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=16428, ...}) = 0
mmap2(0x944000, 12408, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x944000
mmap2(0x946000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1) = 0x946000
close(3) = 0
open("/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/libm.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/libm.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\20\344\221\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=208352, ...}) = 0
mmap2(0x91b000, 155760, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x91b000
mmap2(0x940000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x24) = 0x940000
close(3) = 0
open("/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/libcrypt.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/libcrypt.so.1", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\340\366\2\0064\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=45288, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fe3000
mmap2(0x602f000, 201020, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x602f000
mmap2(0x6038000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x8) = 0x6038000
mmap2(0x603a000, 155964, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x603a000
close(3) = 0
open("/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/libutil.so.1", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/libutil.so.1", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0 \232\234\0054\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=15164, ...}) = 0
mmap2(0x59c9000, 12428, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x59c9000
mmap2(0x59cb000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1) = 0x59cb000
close(3) = 0
open("/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/libpthread.so.0", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/libpthread.so.0", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0000\350\224\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=125612, ...}) = 0
mmap2(0x94a000, 90592, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x94a000
mmap2(0x95d000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x12) = 0x95d000
mmap2(0x95f000, 4576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x95f000
close(3) = 0
open("/usr/lib/perl5/5.8.8/i386-linux-thread-multi/CORE/libc.so.6", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/lib/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\320\257~\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1606808, ...}) = 0
mmap2(0x7d5000, 1324452, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7d5000
mmap2(0x913000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x13e) = 0x913000
mmap2(0x916000, 9636, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x916000
close(3) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fe2000
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fe1000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb7fe16c0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
mprotect(0x775000, 4096, PROT_READ) = 0
mprotect(0x585000, 4096, PROT_READ) = 0
mprotect(0x946000, 4096, PROT_READ) = 0
mprotect(0x940000, 4096, PROT_READ) = 0
mprotect(0x6038000, 4096, PROT_READ) = 0
mprotect(0x59cb000, 4096, PROT_READ) = 0
mprotect(0x95d000, 4096, PROT_READ) = 0
mprotect(0x913000, 8192, PROT_READ) = 0
mprotect(0x7cc000, 4096, PROT_READ) = 0
munmap(0xb7fe4000, 39391) = 0
set_tid_address(0xb7fe1708) = 29253
set_robust_list(0xb7fe1710, 0xc) = 0
futex(0xbfa70c84, FUTEX_WAKE_PRIVATE, 1) = 0
rt_sigaction(SIGRTMIN, {0x94e3d0, [], SA_SIGINFO}, NULL, 8) = 0
rt_sigaction(SIGRT_1, {0x94e2e0, [], SA_RESTART|SA_SIGINFO}, NULL, 8) = 0
rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
getrlimit(RLIMIT_STACK, {rlim_cur=10240*1024, rlim_max=RLIM_INFINITY}) = 0
uname({sys="Linux", node="localhost.localdomain", ...}) = 0
rt_sigaction(SIGFPE, {SIG_IGN, [FPE], SA_RESTART}, {SIG_DFL, [], 0}, 8) = 0
brk(0) = 0x885e000
brk(0x887f000) = 0x887f000
getuid32() = 0
geteuid32() = 0
getgid32() = 0
getegid32() = 0
open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=56416256, ...}) = 0
mmap2(NULL, 2097152, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7de1000
close(3) = 0
mmap2(NULL, 135168, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7dc0000
open("/dev/urandom", O_RDONLY|O_LARGEFILE) = 3
read(3, "\206BZ\333", 4) = 4
close(3) = 0
time(NULL) = 1247747839
stat64("/usr/lib/perl5/site_perl/5.8.7", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/usr/lib/perl5/site_perl/5.8.6", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/usr/lib/perl5/site_perl/5.8.5", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/usr/lib/perl5/vendor_perl/5.8.7", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/usr/lib/perl5/vendor_perl/5.8.6", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/usr/lib/perl5/vendor_perl/5.8.5", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
_llseek(0, 0, 0xbfa70800, SEEK_CUR) = -1 ESPIPE (Illegal seek)
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
_llseek(1, 0, 0xbfa70800, SEEK_CUR) = -1 ESPIPE (Illegal seek)
ioctl(2, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfa707d8) = -1 ENOTTY (Inappropriate ioctl for device)
_llseek(2, 0, [10847], SEEK_CUR) = 0
open("q.pl", O_RDONLY|O_LARGEFILE) = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfa708b8) = -1 ENOTTY (Inappropriate ioctl for device)
_llseek(3, 0, [0], SEEK_CUR) = 0
fcntl64(3, F_SETFD, FD_CLOEXEC) = 0
fstat64(3, {st_mode=S_IFREG|0744, st_size=90, ...}) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
readlink("/proc/self/exe", "/usr/bin/perl", 4095) = 13
read(3, "#!/usr/bin/perl\r\n\r\nopen(FH,\"<q.t"..., 4096) = 90
read(3, "", 4096) = 0
close(3) = 0
open("q.txt", O_RDONLY|O_LARGEFILE) = 3
ioctl(3, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbfa707c8) = -1 ENOTTY (Inappropriate ioctl for device)
_llseek(3, 0, [0], SEEK_CUR) = 0
fstat64(3, {st_mode=S_IFREG|0744, st_size=90, ...}) = 0
fcntl64(3, F_SETFD, FD_CLOEXEC) = 0
read(3, "#!/usr/bin/perl\r\n\r\nopen(FH,\"<q.t"..., 4096) = 90
write(1, "#!/usr/bin/perl\r\n", 17) = 17
time(NULL) = 1247747839
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({2, 0}, {2, 0}) = 0
time(NULL) = 1247747841
write(1, "\r\n", 2) = 2
time(NULL) = 1247747841
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({2, 0}, {2, 0}) = 0
time(NULL) = 1247747843
write(1, "open(FH,\"<q.txt\") or die;\r\n", 27) = 27
time(NULL) = 1247747843
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({2, 0}, {2, 0}) = 0
time(NULL) = 1247747845
write(1, "while (<FH>) {\r\n", 16) = 16
time(NULL) = 1247747845
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({2, 0}, {2, 0}) = 0
time(NULL) = 1247747847
write(1, " print ;\r\n", 11) = 11
time(NULL) = 1247747847
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({2, 0}, {2, 0}) = 0
time(NULL) = 1247747849
write(1, " sleep 2;\r\n", 12) = 12
time(NULL) = 1247747849
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({2, 0}, {2, 0}) = 0
time(NULL) = 1247747851
write(1, "}\r\n", 3) = 3
time(NULL) = 1247747851
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({2, 0}, {2, 0}) = 0
time(NULL) = 1247747853
write(1, "\r\n", 2) = 2
time(NULL) = 1247747853
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
nanosleep({2, 0}, {2, 0}) = 0
time(NULL) = 1247747855
read(3, "", 4096) = 0
close(3) = 0
exit_group(0) = ?
これを見ると、
read(3, "#!/usr/bin/perl\r\n\r\nopen(FH,\"<q.t"..., 4096) = 90
とあるので、4096バイトまでは一気に読み込んでいることがわかります。
じゃー、4096バイト以上のファイルならどうなんだ説がでてくるわけで。
それでも、ちゃんとread文がうごいてしまうわけですよ。
非常に摩訶不思議なのですが、
・ファイルを削除したからといって、実体が即なくなったわけではない
・んなもんで、ファイルファンドルではまだアクセス可能だった!
なんか、うそくせぇ・・・でも、straceの動きとか、inodeの話を考えると、そうなんだよな。。
結論
・小さなファイルだと、読み込み中に上書き・削除したからといって、壊れることはない。
だからといって、それで安心してるとまた足元すくわれるわけですが。
|