2009-08-16 31 views
3

我寫了一些測試代碼使用Proc::Daemon,什麼我的測試代碼是像以前一樣:爲什麼我的程序在使用Proc :: Daemon時無法寫入文件?

#! /usr/bin/perl 

use strict; 
use warnings; 
use Proc::Daemon; 

Proc::Daemon::Init(); 
my $continue = 1; 
$SIG{TERM} = sub { $continue = 0 ; } 

while ($continue) { 
    sleep(5) ; 
    &greeting ; 
} 

sub greeting { 
    open (FH, ">>/home/daogu/foo") or die "can't open it" ; 
    print FH "hello word\n" ; 
    close FH ; 
} 

後,我開始了玩具守護,我發現沒有什麼實際已被寫入「foo」。有人可以解釋爲什麼會發生這種情況?謝謝。

+2

顯然$繼續變爲0有時你從‘休眠5’醒了。一些基本的調試可能會幫助你瞭解正在發生的事情,並且可能花費的時間少於切割到網站中的時間。 – jrockway 2009-08-16 15:56:13

+0

我想你想在第9行末尾加一個分號:'$ SIG {TERM} = sub {$ continue = 0; };'這可能是一個錯字,我不認爲這是根本問題。 – Telemachus 2009-08-16 16:13:36

+0

使用'open()'的三個參數形式。 – 2009-08-16 16:29:41

回答

7

首先,你需要一個分號終止在第9行分配:

$SIG{TERM} = sub { $continue = 0 ; }; 

,直到我說的是,你的程序將不能運行,所以我猜你的是,在腳本,並在這裏錯過了。

除此之外,我懷疑Guss是對的,並且您有權限問題。這是一種檢查方法。打開一個單獨的終端並運行top。啓動守護進程腳本,您將看到一個Perl進程顯示。如果問題是權限,您將很快看到Perl進程消失。該腳本在子例程中死亡,但您嘗試獲取有用的錯誤消息從不出現,因爲該守護程序在此時無法訪問您的終端。

改變此測試的快速方法是在子例程中將die更改爲warn。如果這樣做,守護程序將繼續運行(檢查終端運行top以確認此操作)。但如果問題是權限,您仍然將看不到創建或寫入的文件。

編輯:是的,權限麻煩+沒有訪問STDERR =一個死的,沉默的守護進程。試試這個版本,但要確保你可以寫切換爲STDERR日誌:

Proc::Daemon::Init(); 
my $continue = 1; 
$SIG{TERM} = sub { $continue = 0 ; }; 

while ($continue) { 
    sleep(5); 
    greeting(); 
} 

sub greeting { 
    open STDERR, '>>', '/Users/telemachus/log' 
     or die "Can't reopen STDERR to log: $!"; 
    open my $fh, '>>', '/usr/local/foo' 
     or warn "Can't open /usr/local/foo for writing: $!"; 
    print $fh "hello word\n"; 
    close $fh; 
} 

你可能會看到一大堆這在你的日誌:

燦寫「T開富:權限在上封閉的文件句柄$ FH守護線21 印刷()在後臺行否認22

+0

我總是發現strace(1)在追蹤這些情況時不會改變原始代碼。 – 2009-08-17 10:39:42

+0

@Dominic:雖然「不改變原始代碼」聽起來很誘人,但我不能騙你。我無法破譯'strace'(或者'dtrace'和'dtruss'的輸出以供其他人在Mac上尋找它)來拯救我的生命。我應該真的學習如何。 – Telemachus 2009-08-17 11:10:14

3

你的腳本對我來說很好看。最有可能的問題是文件權限 - 確保您有權創建文件的目錄的寫入權限,或者文件已存在且您擁有對文件本身的寫入權限。

我在我的機器上運行你的腳本,它工作正常。

+1

真的嗎?即使9號線上缺少分號?我的實驗給出了這個:守護程序第11行語法錯誤,接近「){」'和on和on。 – Telemachus 2009-08-16 16:12:48

+0

是的,顯然我解決了這個問題 - 我只是覺得它不重要,因爲編譯器會立即提醒你注意這個問題。 – Guss 2009-08-16 17:18:10

+1

夠公平了,我沒有爲你付出代價。但是,你說「你的腳本對我來說很好看」,這對我來說很奇怪,因爲他的程序沒有編譯。 Perl告訴你「我弄溼了牀」,但它並沒有確切地說明在哪裏。 (這很容易找到,但編譯器並沒有從字面上說:「嗨,你需要在第9行的匿名子程序結尾處有一個分號。」)對我來說,更大的問題是,留下一個分號匿名subs是Perl中一個很常見的問題,所以我認爲它值得一提。編譯器提示的問題只有在*知道*需要分號時才容易找到。 – Telemachus 2009-08-16 17:33:58

相關問題