2009-11-30 28 views
5

Tôi chắc rằng ai đó có thể trả lời câu hỏi này rất nhanh chóng, nhưng tôi chỉ mới làm quen với ...Tại sao Perl CGI của tôi phàn nàn về "Kết thúc tiêu đề kịch bản sớm"?

Tôi đang cố gắng sửa đổi demarc (một công cụ giám sát mạng đơn giản) để thực hiện cuộc gọi hệ thống đến một đơn giản kịch bản. Bản thân kịch bản không làm gì cả, tôi chỉ đang cố gắng thực hiện 'chứng minh-khái niệm' vì tôi tiếp tục gặp lỗi máy chủ nội bộ. Quyền cho kịch bản đã được thiết lập để 777. Khi tôi nhận xét hệ thống() gọi, mọi thứ đều ổn. Vì vậy, làm cho tôi nghi ngờ rằng đó là hệ thống() gọi nơi xảy ra lỗi. Tôi cũng đã thử exec(), nhưng điều đó cũng không hoạt động. Lỗi này không thể có trong bản thân tập lệnh vì chỉ có một "kiểm thử" trong đó.

Tôi đã bỏ lỡ bất kỳ quyền nào hoặc có cách nào khác để thực hiện công việc này không? Bất kỳ tư vấn sẽ được đánh giá cao.

sub generate_ticket { 
    my @args = ("$base_path/test.pl"); 
    exec(@args); 
} 

này được gọi là nơi nào đó trong tập tin như thế này:

} elsif ($FORM{'delete_type'}=~/generate/) { 
    my $message = &generate_ticket($delete_array_ref); 
    #&ack_events($delete_array_ref); 
    $events_deleted = (@$delete_array_ref); 
    &push_message("<FONT COLOR=red><B>Result: $message.</B></FONT>"); 
} 

test.pl:

#!/usr/bin/perl 
print "Test"; 

log Lỗi: [Mon 30 tháng 11 14:58:22 2009] [ lỗi] [client 127.0.0.1] Kết thúc sớm tiêu đề tập lệnh: demarc, referer: http://localhost/dm/demarc?td=show_events&limit=60&sid=35

+1

Giúp chúng tôi giúp bạn bằng cách nói cho chúng ta những gì các đối số cho hệ thống của bạn() hoặc cuộc gọi exec() đang có. –

+0

hiển thị cho chúng tôi một số mã. –

+0

Đã sửa đổi bài đăng của tôi để thêm mã mẫu ... – EDJ

Trả lời

0

Có vẻ như bạn muốn ghi lại đầu ra từ test.pl. Sử dụng system hoặc exec sẽ không đạt được điều đó (và với exec, tập lệnh chính của bạn sẽ không còn được chạy trước thời gian test.pl được chạy).

Thay vào đó, bạn có thể sử dụng backticks:

my $message = `$base_path/test.pl`; 
+0

Vâng ... không thực sự ngay bây giờ, nhưng có, tôi sẽ muốn nắm bắt nó trong tương lai. Ngay bây giờ, tôi chỉ muốn nó vượt qua lỗi máy chủ nội bộ .. Tôi sẽ thử backtick ngay bây giờ .... – EDJ

+0

Điều này thực sự hoạt động, tôi sẽ sử dụng điều này như là phương sách cuối cùng. – EDJ

+0

Nếu điều này làm việc, và hệ thống không, là nó có thể một nơi nào đó bạn có một con đường sai? – Geo

2

Bạn có thể muốn system, không exec:

Chức năng exec thực hiện một hệ thống lệnh và không bao giờ sử dụng hệ thống returns-- thay vì exec nếu bạn muốn nó để trở lại.

Xem tài liệu cho exec.

+0

Tôi đã thử hệ thống() trước khi thử exec(), nhưng nó đã không làm việc cũng ... :) – EDJ

+0

'hệ thống' sẽ ít nhất là không hoạt động * khác nhau * theo cách sẽ tỏa sáng nhiều hơn cho vấn đề. 'exec' là hoàn toàn sai. – hobbs

+0

@hobss: Tôi hiểu rồi. Cảm ơn vì tiền hỗ trợ. – EDJ

1

Xem 500 Server Error trong danh sách Câu hỏi thường gặp Perl.

Bạn đã đảm bảo tập lệnh chạy từ dòng lệnh, phải không?

+0

Có ... Tôi đã thử nghiệm lần đầu tiên ... – EDJ

2

Tôi đoán điều đầu tiên bạn phải làm là kiểm tra nhật ký máy chủ web của bạn, thường có lý do để ném lỗi máy chủ nội bộ.

+0

Đã kiểm tra, đăng nó như là một phần của câu hỏi của tôi. :) – EDJ

0

Tốt nhất là bạn nên thử phiên bản đơn giản hơn về những gì bạn đang cố gắng làm.

Hãy thử điều này:

  • Tạo một cái gì đó giống như test2.pl mà làm điều gì đó đơn giản hơn.
  • Chạy tập lệnh được đơn giản hóa.

    #!/bin/perl 
    use feature 'say'; 
    use strict; 
    use warnings; 
    use Data::Dumper; 
    use English qw<$OS_ERROR>; 
    
    my $rc = system("$base_path/test2.pl"); 
    say "\$rc=$rc"; 
    say $OS_ERROR; 
    

Bây giờ,

  1. Nếu $rc0. Sau đó, nó đã làm việc để thực thi kịch bản theo cách đó. Nếu không, $OS_ERROR sẽ cho bạn biết.
  2. Nếu tất cả điều này hoạt động, thì bạn có thể thử thực thi tập lệnh gốc và xem nó có hoạt động không.
  3. Nếu điều đó hoạt động, thì đó có thể là trạng thái của chương trình tại thời điểm được gọi.

Nhưng, như những người khác đã lưu ý, trừ khi bạn đã hoàn tất chạy tập lệnh, exec -ing từ tập lệnh không phải là những gì bạn muốn làm, ngay cả khi đó là một chương trình. Điều đó sẽ chỉ tải chương trình trên không gian được sử dụng bởi kịch bản.

Sử dụng qx hoặc backticks (`) sẽ cho phép dòng lệnh được diễn giải bởi trình bao sẽ xử lý các shebang (#!) trong tập lệnh perl và trả về kết quả của tập lệnh.

-2

Tôi đã luôn luôn là một fan hâm mộ của việc sử dụng qx cho hệ thống của tôi gọi:

my @array = qx(ls -1); 

hệ thống trả về một chuỗi mà sau đó cần phải được phân tích, bởi qx trả về một mảng, và nếu bạn biết dòng 4 có thông tin bạn cần, bạn có thể đến đó và lấy nó.

+0

'hệ thống' không trả về một chuỗi, nó trả về một giá trị trả về số nguyên và không thu được đầu ra của chương trình chút nào. 'qx' trả về một danh sách các dòng * hoặc * một chuỗi tùy thuộc vào ngữ cảnh. – hobbs

+0

Bạn có thể trỏ đến một số tài liệu liệt kê qx xuất chuỗi/mảng tùy thuộc vào ngữ cảnh không? Tôi chưa bao giờ thấy hành vi đó – MikeEL

7

"Kết thúc tiêu đề tập lệnh sớm" không phải là thông báo lỗi hữu ích khủng khiếp. Nó có thể được gây ra bởi bất kỳ hành một số điều, chẳng hạn như:

  • không được thực thi (cho phép vấn đề)
  • không biên soạn (lỗi cú pháp, vấn đề phụ thuộc, vv)
  • chấm dứt sớm trong thường xuyên thực hiện
  • sản xuất cái gì đó khác hơn là tiêu đề HTTP đúng như kết quả đầu tiên của kịch bản của bạn

Tuy nhiên, trong trường hợp này, nếu chúng ta muốn lấy một ví dụ kịch bản của bạn theo nghĩa đen (print "TEST") và bạn xuất kết quả này trước tiêu đề HTTP của mình, trước tiên bạn không tạo tiêu đề HTTP, vì vậy đó là tiêu đề cuối cùng. Máy chủ web dự kiến ​​tiêu đề, không phải là "TEST".

Nếu không phải như vậy, chúng tôi cần xem thêm ngữ cảnh mã của bạn để biết điều gì có thể đã xảy ra. Có thể là một vấn đề quyền thực hiện test.pl, ví dụ.

1

Nó không phải là Perl CGI phàn nàn, mà là Apache. Apache nói rằng tập lệnh CGI của bạn không xuất ra các tiêu đề bắt buộc, vì vậy đó là điều đầu tiên bạn cần đạt được.

Tôi luôn thử CGI bằng tập lệnh printenv trước, ví dụ:

#!/usr/bin/env perl 

use warnings; 
use strict; 

print "Content-type: text/plain\r\n\r\n"; 
print "$_ => $ENV{$_}\r\n" for sort keys %ENV; 

Khi hoạt động, hãy thử cái gì khác.

2

Một cách để tìm nguyên nhân của điều sớm là làm cho các lỗi xảy ra với trình duyệt.Bạn chỉ cần gửi tiêu đề kiểu nội dung sớm trong ứng dụng, ví dụ như thế này, ở đâu đó ở đầu mã của bạn:

BEGIN { 
    print "Content-type: text/plain\n\n"; 
} 

Bây giờ bạn sẽ có thể thấy lỗi trong trình duyệt.

0

[client 127.0.0.1] Premature cuối tiêu đề kịch bản:

bạn cần khai báo trong tập tin pl của bạn (trong trường hợp đó bạn muốn chạy trong trình duyệt) header loại nội dung. Dưới đây là ví dụ:

#!c:/wamp/bin/perl/bin/perl.exe 

print "Content-type: text/html\n\n"; 
print "<html><head><title>Test</title></head>"; 
print "<body>"; 
print "Hello"; 
print "</body></html>"; 

### 

kiểm tra dòng thông báo: print "Content-type: text/html \ n \ n"; < - dòng này là rất quan trọng

Grettings

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