2010-07-09 41 views

Trả lời

30

String::ShellQuote, nhưng hầu hết thời gian không cần thiết. Bạn chỉ đơn giản là có thể tránh gọi trình bao bằng cách lập trình cẩn thận. Ví dụ: system takes a list of arguments thay vì chuỗi.

Thực hành tốt nhất:

use IPC::System::Simple qw(systemx); 
systemx($command, @arguments); 

require IPC::System::Simple; 
use autodie qw(:all); 
system([@allowed_exit_values], $command, @arguments); 
+5

Vâng, chỉ cần tránh vỏ hoàn toàn nếu có thể. –

+3

Công việc tốt trả lời [câu hỏi XY] (http://www.perlmonks.org/index.pl?node_id=542341) với giải pháp thích hợp. :) – Ether

+0

Điều này có thể giúp mặc dù khi bạn cần chuyển hướng (vì vậy không thể sử dụng dạng danh sách của hệ thống() gọi) * và * đối số từ các biến? ví dụ. một giải pháp cho nỗ lực thất bại sau đây để 'ls 'f o o'':' my $ foo =' f o o '; my $ result = \ 'ls $ foo 2> &1\';'? – artfulrobot

3

Perl có thể phù hợp với những điều sau nói chức năng:

thêm dấu nháy đơn xung quanh một chuỗi và dấu ngoặc kép/thoát bất kỳ dấu nháy đơn hiện

http://php.net/manual/en/function.escapeshellarg.php#function.escapeshellarg

như thế này:

sub php_escapeshellarg { 
    my $str = @_ ? shift : $_; 
    $str =~ s/((?:^|[^\\])(?:\\\\)*)'/$1'\\''/g; 
    return "'$str'"; 
} 
+1

Điều này không hoạt động. Cân nhắc truyền chuỗi 'foo'bar' đến hàm. Nó sẽ tạo ra chuỗi sau: ''foo \' bar''. Nhưng có thể không có dấu nháy đơn nào trong dấu nháy đơn. – josch

0

tôi phải đồng ý với @daxim. Nhưng có một số trường hợp mà bạn không thể sử dụng điều này như truyền lệnh trên một socket đến một chương trình không phải là perl hoặc không có sẵn mô-đun IPC. Tôi cũng nhìn vào regexp được đưa ra bởi @axeman và có vẻ hơi phức tạp với tôi. Tôi có thể sai, nhưng tôi nghĩ bạn không cần phải thoát khỏi các dấu gạch chéo ngược trong các chuỗi trích dẫn đơn lẻ cho một lệnh. Vì vậy, bạn chỉ có thể làm điều này:

sub escapeshellarg { 
    my $arg = shift; 

    $arg =~ s/'/'\\''/g; 
    return "'" . $arg . "'"; 
} 

Nếu ai có lý do nào đó, tại sao điều này có thể không an toàn, tôi muốn biết. Tôi đã thử nghiệm nó bằng cách sử dụng bất kỳ loại trickery tôi có thể nghĩ đến để làm cho shell thực hiện mã tùy ý, mà không thành công, mà làm cho tôi nghĩ rằng regexp này là giống như việc thực hiện PHP.

Trong triển khai PHP, nó nói rằng tất cả những gì nó làm là: thêm dấu nháy đơn xung quanh một chuỗi và báo giá/thoát bất kỳ dấu nháy đơn hiện có nào.

Điều duy nhất regexp này thực hiện là gì. Suy nghĩ?

+2

Tôi hoài nghi, tôi sẽ luôn luôn thích cpantesters đã được chứng minh [String :: ShellQuote] (http://p3rl.org/String::ShellQuote) đã được triển khai trong tự nhiên trong nhiều năm và có các báo cáo lỗi và -fix để hiển thị cho nó qua một regex ad-hoc của người dùng SO. Bạn có thể so sánh mã của nó với bạn và tìm ra chính mình những gì bạn đang thiếu. – daxim

+0

@daxim chúng không quá dễ so sánh: http://api.metacpan.org/source/ROSCH/String-ShellQuote-1.04/ShellQuote.pm – dlamblin

+0

Darn, xin lỗi tôi đã vô tình downvoted câu trả lời của bạn và bây giờ tôi không thể hoàn tác nó . :( – josch

1

một này làm việc cho tôi trong BASH:

sub escape_shell_param($) { 
    my ($par) = @_; 
    $par =~ s/'/'"'"'/g; # "escape" all single quotes 
    return "'$par'";  # single-quote entire string 
} 

Nó dựa trên những điều khoản sau đây lấy từ các trang BASH người đàn ông:

  1. Kèm theo nhân vật trong dấu nháy đơn bảo tồn các giá trị văn chương của mỗi ký tự trong dấu ngoặc kép.
  2. Một trích dẫn duy nhất có thể không xảy ra giữa các dấu nháy đơn, ngay cả khi có dấu gạch chéo ngược đứng trước.
  3. Bao gồm các ký tự trong ngoặc kép giữ nguyên giá trị bằng chữ của tất cả các ký tự trong dấu ngoặc kép, ngoại trừ $, `, \, và khi mở rộng lịch sử được bật,!.

Từ (2.) chúng ta biết rằng dấu gạch chéo ngược không thể được sử dụng để thoát khỏi các qoutes đơn lẻ, nhưng từ (3.) nó ngụ ý rằng các dấu ngoặc kép giữ nguyên giá trị chữ của dấu nháy đơn (hay còn gọi là escape). Cũng lưu ý rằng mục đích duy nhất của dấu ngoặc kép là thay đổi ý nghĩa của các ký tự được trích dẫn (không có các đối tượng chuỗi đặc biệt hoặc những thứ tương tự được tạo) và sau khi mở rộng tất cả các ký tự chữ liên tiếp được nối với nhau. Sau đó, 'foo''bar' cũng giống như foobar.

Chức năng ở trên là trích dẫn một lần toàn bộ chuỗi để không charcter nào trong đó có ý nghĩa đặc biệt. Tuy nhiên, để cho phép sự hiện diện của các ký tự trích dẫn đơn, chuỗi được tách ra ở bất kỳ vị trí nào được tìm thấy và các thao tác sau được thực hiện: chuỗi con trước đó được hoàn thành ('), sau đó trích dẫn một trích dẫn kép được giới thiệu ("'") và chuỗi con tiếp theo được bắt đầu ('). Đó là lý do tại sao ' được thay thế toàn cầu bởi '"'"'.

Ví dụ (giả):

foo'bar => 'foo' + "'" + 'bar' 
Các vấn đề liên quan