2011-11-14 26 views
21

Tôi có tập lệnh Perl mà tôi muốn sao chép. Về cơ bản kịch bản perl này sẽ đọc một thư mục mỗi 30 giây, đọc các tập tin mà nó tìm thấy và sau đó xử lý dữ liệu. Để giữ cho nó đơn giản ở đây xem xét các kịch bản Perl sau (gọi là synpipe_server, có một liên kết tượng trưng của kịch bản này trong /usr/sbin/):Gọi tới daemon trong tập lệnh /etc/init.d đang chặn, không chạy ở chế độ nền

#!/usr/bin/perl 
use strict; 
use warnings; 

my $continue = 1; 
$SIG{'TERM'} = sub { $continue = 0; print "Caught TERM signal\n"; }; 
$SIG{'INT'} = sub { $continue = 0; print "Caught INT signal\n"; }; 

my $i = 0; 
while ($continue) { 
    #do stuff 
    print "Hello, I am running " . ++$i . "\n"; 
    sleep 3; 
} 

Vì vậy, kịch bản này về cơ bản sẽ in một cái gì đó mỗi 3 giây.

Sau đó, như tôi muốn daemonize kịch bản này, tôi cũng đã đưa kịch bản bash này (còn gọi là synpipe_server) trong /etc/init.d/:

#!/bin/bash 
# synpipe_server : This starts and stops synpipe_server 
# 
# chkconfig: 12345 12 88 
# description: Monitors all production pipelines 
# processname: synpipe_server 
# pidfile: /var/run/synpipe_server.pid 
# Source function library. 
. /etc/rc.d/init.d/functions 

pname="synpipe_server" 
exe="/usr/sbin/synpipe_server" 
pidfile="/var/run/${pname}.pid" 
lockfile="/var/lock/subsys/${pname}" 

[ -x $exe ] || exit 0 

RETVAL=0 

start() { 
    echo -n "Starting $pname : " 
    daemon ${exe} 
    RETVAL=$? 
    PID=$! 
    echo 
    [ $RETVAL -eq 0 ] && touch ${lockfile} 
    echo $PID > ${pidfile} 
} 

stop() { 
    echo -n "Shutting down $pname : " 
    killproc ${exe} 
    RETVAL=$? 
    echo 
    if [ $RETVAL -eq 0 ]; then 
     rm -f ${lockfile} 
     rm -f ${pidfile} 
    fi 
} 

restart() { 
    echo -n "Restarting $pname : " 
    stop 
    sleep 2 
    start 
} 

case "$1" in 
    start) 
     start 
    ;; 
    stop) 
     stop 
    ;; 
    status) 
     status ${pname} 
    ;; 
    restart) 
     restart 
    ;; 
    *) 
     echo "Usage: $0 {start|stop|status|restart}" 
    ;; esac 

exit 0 

Vì vậy, (nếu tôi có hiểu rõ doc cho daemon) kịch bản Perl nên chạy ở chế độ nền và đầu ra nên được chuyển hướng đến /dev/null nếu tôi thực hiện:

service synpipe_server start 

Nhưng đây là những gì tôi nhận được thay vì:

[[email protected] init.d]# service synpipe_server start 
Starting synpipe_server : Hello, I am running 1 
Hello, I am running 2 
Hello, I am running 3 
Hello, I am running 4 
Caught INT signal 
                  [ OK ] 
[[email protected] init.d]# 

Vì vậy, nó bắt đầu kịch bản Perl nhưng chạy nó mà không cần tách nó khỏi phiên đầu cuối hiện tại, và tôi có thể thấy đầu ra được in trong bảng điều khiển của tôi ... mà không thực sự là những gì tôi mong đợi. Hơn nữa, tệp PID trống (hoặc chỉ với nguồn cấp dữ liệu dòng, không có pid được trả về bởi daemon).

Có ai có bất kỳ ý tưởng nào về những gì tôi đang làm sai không?

EDIT: có lẽ tôi nên nói rằng tôi đang sử dụng máy Red Hat.

Scientific Linux SL release 5.4 (Boron) 

Cảm ơn, Tony

+3

Thay vì viết một daemon để thăm dò ý kiến ​​cho những thay đổi, bạn có thể sử dụng inotify http://en.wikipedia.org/wiki/Inotify thông báo cho bạn khi một sự thay đổi đã xảy ra. Dễ dàng mã hóa, hiệu quả hơn và có thể xem các cập nhật nhanh hơn. Có một số mô-đun CPAN để nói chuyện với nó. http://search.cpan.org/search?query=inotify&mode=all – Schwern

+0

Cảm ơn, đây là thông tin hữu ích, tôi chắc chắn sẽ xem xét Inotify. – tony

+0

@Schwern: điều đó không thay đổi thực tế là tôi phải chạy một daemon ở chế độ nền đang đợi thông báo inotify, không ?? – tony

Trả lời

15

cuối cùng tôi lại viết chức năng khởi động trong tập lệnh init bash và tôi không sử dụng daemon nữa.

start() { 
    echo -n "Starting $pname : " 
    #daemon ${exe} # Not working ... 
    if [ -s ${pidfile} ]; then 
     RETVAL=1 
     echo -n "Already running !" && warning 
     echo 
    else 
     nohup ${exe} >/dev/null 2>&1 & 
     RETVAL=$? 
     PID=$! 
     [ $RETVAL -eq 0 ] && touch ${lockfile} && success || failure 
     echo 
     echo $PID > ${pidfile} 
    fi 
} 

Tôi kiểm tra xem tệp pid chưa tồn tại (nếu có, chỉ cần viết cảnh báo). Nếu không, tôi sử dụng

nohup ${exe} >/dev/null 2>&1 & 

để bắt đầu tập lệnh.

Tôi không biết nếu nó an toàn theo cách này (?) Nhưng nó hoạt động.

+2

Tôi đã sử dụng một cái gì đó tương tự, nhưng được sử dụng 'daemon' bên cạnh nohup để cung cấp đầu ra được hiển thị khi tập lệnh đã được bắt đầu. Đó là một gợi ý trực quan hơn nữa, vì thông điệp [OK] sẽ luôn trở lại như OK miễn là nohup đã chạy: 'daemon 'nohup $ {exe}>/dev/null 2> & 1 &" ' làm ví dụ. – Rohaq

+0

tony, sẽ không daemon này chết khi vỏ của bạn chấm dứt? Hay không nohup ngăn chặn điều đó? – Mark

+0

Có, khi trình kết thúc kết thúc, quá trình tạo bởi nohup vẫn còn sống. – tony

0

Theo man daemon cú pháp chính xác là

daemon [options] -- [command] [command args] 

init script của bạn khởi động nên chạy cái gì đó như:

daemon --pidfile ${pidfile} -- ${exe} 
+3

Cảm ơn yko, nhưng nó không phải là điều này vì việc sử dụng 'daemon' của tôi nói: 'daemon [+/- nicelevel] {program}'. Có lẽ chúng tôi không có cùng phiên bản. – tony

+0

@tony Bạn có thể giải quyết vấn đề sử dụng lệnh không? –

+0

@tony Tôi đã kết thúc việc cài đặt [daemon từ libslack] (http://libslack.org/daemon/#download) –

0

Như đã nói here, có vẻ như quy trình cần được gửi tới nền sử dụng &. Daemon không làm điều đó cho bạn.

1

Cách thích hợp để daemonize một quy trình là nó tách khỏi thiết bị đầu cuối bởi chính nó. Đây là cách hầu hết các bộ phần mềm lớn hơn làm điều đó, ví dụ, apache.

Lý do đằng sau daemon không làm những gì bạn mong chờ từ tên gọi của nó, và làm thế nào để thực hiện một quá trình unix tách vào nền, có thể được tìm thấy here trong phần 1,7 Làm thế nào để có được chương trình của tôi để hành động như một daemon?

Đơn giản gọi chương trình ở chế độ nền không thực sự phù hợp cho các chương trình chạy dài này; không chính xác tách quy trình khỏi phiên thiết bị đầu cuối đã bắt đầu quá trình đó. Ngoài ra, cách thông thường để bắt đầu các trình tiện ích đơn giản chỉ cần đưa ra lệnh theo cách thủ công hoặc từ một tập lệnh rc; daemon được dự kiến ​​sẽ tự đặt chính nó vào nền.

Để đọc thêm về chủ đề này: What's the difference between nohup and a daemon?

Các vấn đề liên quan