2010-06-22 28 views
5

Tôi có tập lệnh perl, script.pl, khi chạy, thực hiện một ngã ba, quá trình cha mẹ sẽ xuất ra pid của nó thành tệp rồi thoát trong khi quá trình con xuất ra một cái gì đó để STOUT và sau đó đi vào một vòng lặp while.perl fork không hoạt động bình thường khi chạy từ xa (qua ssh)

$pid = fork(); 

if (! defined $pid) 
{ 
    die "Failed to fork."; 
} 
#Parent process 
elsif($pid) 
{ 
    if(!open (PID, ">>running_PIDs")) 
    { 
     warn "Error opening file to append PID"; 
    } 
    print PID "$pid \n"; 
    close PID; 
} 
#child process 
else 
{ 
    print "Output started"; 

    while($loopControl)  
    { 
      #Do some stuff 
    } 
} 

Điều này làm việc tốt khi tôi gọi địa phương là: perl script.pl.

Tập lệnh in ra một số thứ rồi trả về điều khiển quay lại trình bao. (trong khi quá trình con đi vào vòng lặp của nó trong nền).

Tuy nhiên, khi tôi gọi đây là thông qua kiểm soát ssh không bao giờ quay trở lại vào vỏ (cũng không phải là "Output bắt đầu" dòng bao giờ in

ví dụ:. Script perl $ ssh [email protected]'. pl'

Tuy nhiên, điều thú vị là, quá trình đứa trẻ không ương (tôi có thể nhìn thấy nó khi tôi gõ ps)

bất cứ ai có thể giải thích whats going on

EDIT:.?

Tôi chạy nó dưới gỡ lỗi và nhận được điều này:

### Được chia, nhưng không biết cách tạo TTY mới.

Vì hai trình gỡ rối chiến đấu cho cùng một TTY, đầu vào bị vướng nặng.

Tôi biết cách chuyển đầu ra sang cửa sổ khác trong xterms và chỉ OS/2. Đối với công tắc thủ công, hãy đặt tên của TTY được tạo bằng $ DB :: fork_TTY hoặc xác định hàm DB :: get_fork_TTY() trả về giá trị này.

Mở hệ thống UNIX-like ai có thể có được tên của một TTY cho cửa sổ cho bởi gõ tty, và ngắt kết nối vỏ từ TTY bởi giấc ngủ 1000000.

+1

Nếu có ai có giải pháp cho vấn đề này ngoài 'màn hình' (mà tôi không luôn sẵn sàng), tôi rất muốn xem nó. – mob

Trả lời

8

Bất cứ khi nào bạn khởi động việc làm nền qua lệnh ssh không tương tác , bạn cần phải đóng hoặc loại bỏ stdin, stdout, & stderr. Nếu không, ssh sẽ đợi quá trình nền để thoát. FAQ.

Điều này được gọi là ngắt kết nối hoặc tách khỏi thiết bị đầu cuối điều khiển và là phương pháp hay nhất khi viết công việc nền, không chỉ cho SSH.

Vì vậy, sự thay đổi đơn giản nhất mà không tắt toàn bộ lệnh của bạn là thêm:

#close std fds inherited from parent 
close STDIN; 
close STDOUT; 
close STDERR; 

ngay sau khi print "Output started"; của bạn. Nếu quá trình con của bạn cần in ra định kỳ trong khi chạy, thì bạn sẽ cần chuyển hướng đến tệp nhật ký thay thế.

+0

Tuyệt vời hoạt động hoàn hảo! –

+0

+1 cho liên kết Câu hỏi thường gặp – bitmask

+0

Số giờ đã lãng phí để gỡ lỗi trước khi đọc bài đăng của bạn. Cảm ơn, nó hoạt động! – Shamanu4

4

ssh [email protected] 'nohup perl script.pl'

Bạn không thể để thoát vì vẫn còn một quy trình được đính kèm. Bạn cần phải nohup nó.

+0

Dường như không có tác dụng. = [ –

+0

+1 Chẩn đoán đúng. -1 Đơn thuốc sai. – mob

2

Điều đang xảy ra là ssh đang thực thi 'perl script.pl' làm lệnh trực tiếp. Nếu bạn có 'màn hình' sẵn, bạn có thể làm:

$ ssh [email protected] 'screen -d -m perl script.pl' 

để có nó chạy trên một màn hình tách ra, và lắp lại sau đó với màn hình -r

+0

Công trình này, kiểm soát được trả lại. Điều gì về việc chạy điều này từ xa thông qua ssh khác với chạy nó cục bộ? Howe đến khi nó là địa phương nó không có vấn đề? –

+1

@Razor, khi chạy từ xa, ở đó * là * không có vỏ - trình nền ssh ở phía bên kia chạy và đính kèm chính nó vào tập lệnh. Bạn có thể cũng có thể đạt được những gì bạn muốn bằng cách chạy 'bash -c" perl script.pl "' như lệnh ssh – friedo

+0

Tuy nhiên, quá trình cha mẹ kết thúc, do đó, không nên daemon đính kèm ngừng chạy là tốt? –

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