2011-10-29 37 views
7

Tôi đã gặp phải một vấn đề rất lạ với trình thông dịch lệnh Windows. Nó xảy ra trên cả XP và Windows 7. Mô tả của tôi dưới đây áp dụng cho một kịch bản Perl, nhưng vấn đề này áp dụng để chạy bất kỳ loại chương trình nào trên dòng lệnh có tham số dòng lệnh.Hiệu ứng phụ được trích dẫn kép bị treo trong Windows Command Prompt

Đối với một thử nghiệm Tôi đang sử dụng kịch bản Perl check-params.pl mà chỉ đơn giản kết quả đầu ra những gì nó thấy như thông số -

use strict; 
use warnings; 
while (my $param = shift @ARGV) { 
    print "Param: [$param]\n"; 
} 

Vì vậy, nếu tôi chạy -

perl check-params.pl "a b|<>" c^|^<^>cc 

Sau đó, đầu ra là

[Param: a b|<>] 
[Param: c|<>cc] 

như mong đợi. Các ký tự đặc biệt | <> làm việc tốt bên trong dấu ngoặc kép, nhưng khi báo giá bên ngoài bạn thoát chúng với ^.

Tuy nhiên khi một dấu nháy kép sẽ được thêm vào param ví dụ được trích dẫn trong

perl check-params.pl "a\" b|<>" 

Sau đó, tôi nhận được lỗi -

> was unexpected at this time. 

Nhưng nếu nháy kép đến sau các char đặc biệt | < hoặc>, sau đó nó hoạt động OK.

Bạn có thể dễ dàng khắc phục điều này bằng cách thoát khỏi đặc biệt | <> char với^bên trong tham số được trích dẫn. ví dụ:

perl check-params.pl "a\" b^|" 

Tuy nhiên, không chỉ dấu ngoặc kép thoát kép ảnh hưởng đến ký tự đặc biệt | <> trong thông số hiện tại nhưng nó ảnh hưởng đến các ký tự đặc biệt này bên trong bất kỳ thông số tiếp theo nào.

ví dụ như nếu tôi làm điều này -

perl check-params.pl "aa \"bb" ccc | perl check-pipe.pl 

(nơi check-pipe.pl chỉ đơn giản là kết quả đầu ra những gì các ống nhận được -

use strict; 
use warnings; 
while (<STDIN>) { 
    print "PIPE RECEIVED ---> $_"; 
} 

)

sau đó đầu ra là -

Param: [aa "bb] 
Param: [ccc] 
Param: [|] 
Param: [perl] 
Param: [check-pipe.pl] 

tức là nó xử lý ống | như một nhân vật theo nghĩa đen và không có đường ống nào xảy ra.

Có ai có kinh nghiệm về vấn đề này và biết cách giải quyết nào không?

Tôi đã viết một số tập lệnh Perl để xử lý tệp nhật ký web và một tập lệnh sử dụng regex, mà tôi chuyển vào bên trong thông số được trích dẫn trên dòng lệnh. Regex có thể chứa các ký tự như | <> và nó cũng có thể có dấu ngoặc kép, mà tôi nhập là \ ". Vì vậy, vấn đề trên là cắt xén.

Bất kỳ trợ giúp nào được đánh giá cao, cảm ơn.


Cảm ơn bạn đã trả lời, nhưng khi thử trên XP SP3, tập lệnh Perl nhìn thấy hai tham số dòng lệnh.

Vấn đề này không liên quan đến Perl, ví dụ:

echo "a \"b|c" 

sản xuất lỗi -

'c"' is not recognized as an internal or external command, 
operable program or batch file. 

nhưng

echo "a b|\"c" 

công trình, bởi vì \" xuất phát sau khi char đặc biệt | .

Nó phải là một lỗi trong trình thông dịch lệnh. Tôi sẽ quan tâm để biết thêm về điều này, và tìm một cách giải quyết nếu có thể. Vấn đề này messes lên chạy một số kịch bản hữu ích. Đó là một vấn đề khá rõ ràng đối với một thông dịch viên lệnh. Tôi đã thử trên Windows 7 cũng có, và cùng một vấn đề xảy ra ở đó với các bài kiểm tra tiếng vang trên.


Thông tin bổ sung:

Tôi đã cập nhật các kịch bản check-params.pl và check-pipe.pl để cung cấp thông tin hữu ích hơn: -

check-params.pl: -

use strict; 
use warnings; 
while (my $param = shift @ARGV) { 
    print "COMMAND LINE RECEIVED: [$param]\n"; 
} 

check-pipe.pl: -

use strict; 
use warnings; 
while (<STDIN>) { 
    print "PIPE RECEIVED: $_"; 
} 

while (my $param = shift @ARGV) { 
    print "COMMAND LINE RECEIVED: [$param]\n"; 
} 

Ví dụ chạy: -

perl pl/utils/check-params.pl l1 l1-b l1-c | perl pl/utils/check-pipe.pl l2 l2-b | perl pl/utils/check-pipe.pl l3 l3-b | perl pl/utils/check-pipe.pl united arsenal rangers raith 

sản xuất đầu ra: -

PIPE RECEIVED: PIPE RECEIVED: PIPE RECEIVED: COMMAND LINE RECEIVED: [l1] 
PIPE RECEIVED: PIPE RECEIVED: PIPE RECEIVED: COMMAND LINE RECEIVED: [l1-b] 
PIPE RECEIVED: PIPE RECEIVED: PIPE RECEIVED: COMMAND LINE RECEIVED: [l1-c] 
PIPE RECEIVED: PIPE RECEIVED: COMMAND LINE RECEIVED: [l2] 
PIPE RECEIVED: PIPE RECEIVED: COMMAND LINE RECEIVED: [l2-b] 
PIPE RECEIVED: COMMAND LINE RECEIVED: [l3] 
PIPE RECEIVED: COMMAND LINE RECEIVED: [l3-b] 
COMMAND LINE RECEIVED: [united] 
COMMAND LINE RECEIVED: [arsenal] 
COMMAND LINE RECEIVED: [rangers] 
COMMAND LINE RECEIVED: [raith] 

do đó xác nhận rằng dòng lệnh này sẽ làm việc như mong đợi. Các script sẽ làm việc với bất kỳ số lượng các đường ống trên dòng lệnh.


Thông tin bổ sung:

tôi thấy tôi có thể có được điều này để làm việc sử dụng nhiều biện pháp khắc phục - ví dụ như^"Harry nhắc đến là một ví dụ Đôi khi bạn có thể recraft regex để tránh sử dụng.". Khi có hai \ "chuỗi trước khi char đặc biệt | <> thì vấn đề không xảy ra. Trước khi chạy bất kỳ commmand nào tôi chạy check-params.pl và check-pipe.pl để xác minh cách các kịch bản Perl sẽ thấy các tham số dòng lệnh , ví dụ chỉnh sửa ở trên cho OP của tôi mô tả các tập lệnh này, mà tôi đã sửa đổi kể từ khi OP.

+0

Mặc dù tôi tin rằng tôi đã tìm thấy giải pháp cho bạn (xem chỉnh sửa mới nhất cho câu trả lời của tôi) nếu bạn đang nhập cụm từ thông dụng tương tác, bạn có thể thấy thuận tiện hơn cho tập lệnh của mình dòng lệnh. Bằng cách đó bạn sẽ không phải thoát khỏi tất cả các nhân vật đặc biệt. –

+0

Rất cám ơn thông tin. Tôi đã đạt được ấn tượng từ các bài kiểm tra trong OP của mình rằng \ "là một chuỗi thoát. Tôi không thể nhập thông số dòng lệnh thông qua lời nhắc vì tôi có nhiều lệnh và chúng khá phức tạp. Tôi sao chép và dán chúng từ một tập tin văn bản, và đôi khi tôi sao chép một số và chạy chúng cùng một lúc. (Với Chế độ chỉnh sửa nhanh trên bạn có thể chỉ cần nhấp chuột phải để dán vào cửa sổ lệnh) –

Trả lời

2

Trích dẫn kép trong \ "được coi là khớp với dấu ngoặc kép ban đầu, kết thúc tham số được trích dẫn. Để đưa dấu nháy kép trong một tham số trích dẫn sử dụng hai dấu ngoặc kép:

perl check-params.pl "a"" b|<>" 

nên tạo ra kết quả mà bạn đang mong đợi, tùy thuộc vào cách perl.exe phân tích các thông số dòng lệnh (Tôi đã thử nghiệm sử dụng các kịch bản lệnh như Tôi không cài đặt Perl).Bạn sẽ cần phải thay đổi kịch bản của bạn để "" thay vì \" được coi là một dấu nháy kép

bổ sung:. Dòng lệnh này

echo "a \"b|c" 

kết quả trong một thông báo lỗi bắt đầu c" is not recognized. Đây không phải là một lỗi.

một dấu chéo ngược không phải là một nhân vật chạy thoát, vì vậy dòng lệnh chứa một chuỗi trích dẫn ("a \") tiếp theo là một ống (|) mà làm cho phần còn lại (c") một lệnh bổ sung, mà đầu ra từ lệnh echo được đưa vào.

Nếu bạn thay vì nói

echo "a ""b|c" 

sau đó chỉ là một trong chuỗi trích dẫn ("a ""b|c") và nó sẽ làm việc như mong đợi.

Thật không may, tôi bây giờ có thể khẳng định rằng dòng lệnh phân tích ActivePerl của gây

perl check-params.pl "a"" b|" 

được chia thành hai tham số. Bạn có thể cần phải lấy toàn bộ dòng lệnh (nếu có cách để thực hiện điều đó trong Perl) và phân tích cú pháp đó.

bổ sung:

perl check-params.pl ^"a\^" b^|c^" 

tạo ra kết quả mong muốn. Điều này hoạt động bằng cách thoát khỏi tất cả các ký tự đặc biệt, bao gồm cả dấu ngoặc kép.

+0

^"khá hữu ích và tôi đã thêm điều này với nhiều cách giải quyết của tôi. Có vẻ như có 2 vấn đề ở đây, một là cách trình thông dịch lệnh Windows hoạt động, còn cách khác là cách Perl phân tích cú pháp một dòng lệnh. –

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