2009-11-19 19 views
5

Tôi muốn viết một tập lệnh foo mà chỉ đơn giản là gọi bar với cùng một đối số chính xác được gọi bằng, sử dụng Bash hoặc Perl.Làm cách nào để có được các đối số dòng lệnh chưa sửa đổi để "bọc" một công cụ dòng lệnh khác?

Bây giờ, một cách đơn giản để làm điều này trong perl sẽ

#!/bin/perl 

my $args=join(' ', @ARGV); 
`bar $args`; 

Tuy nhiên, các giá trị trong argv đã được xử lý bằng vỏ, do đó nếu tôi gọi

foo "I wonder, \"does this work\"" 

thanh sẽ được gọi như thế này

bar I wonder "does this work" 

Làm cách nào tôi có thể nhận được dòng lệnh gốc để tôi có thể truyền đúng nguyên văn?

Trả lời

11

Bạn không thể lấy đối số cho tệp thực thi perl trước khi chúng được xử lý bởi trình bao. Bạn có thể, tuy nhiên, chắc chắn rằng vỏ không xử lý chúng một lần nữa :

system('bar', @ARGV); 

vs

system("bar @ARGV"); 

Xem perldoc -f system:

Nếu có chỉ có một vô hướng đối số, đối số được kiểm tra cho các siêu ký tự shell, và nếu có, toàn bộ đối số được chuyển đến hệ thống của hệ thống lệnh shell để phân tích cú pháp (đây là "/ bin/sh -c" trên nền tảng Unix, nhưng khác nhau trên các nền tảng khác). Nếu không có siêu ký tự shell trong đối số , nó được chia thành các từ và được chuyển trực tiếp đến "execvp", hiệu quả hơn.

Nếu bạn cần phải đọc đầu ra của chương trình, sử dụng một quá trình xử lý và vượt qua các đối số trong cùng một cách (không nội suy):

open my $barhandle, '-|', 'bar', @ARGV or die "Can't call bar: $!"; 
while (my $line = <$barhandle>) 
{ 
    # do something with $line... 
} 
close $barhandle; 

Có rất nhiều cách để bạn có thể gọi ra cho một chương trình trong Perl; xem What's the difference between Perl's backticks, system, and exec? để biết tổng quan về các tùy chọn chính.

+0

Một lưu ý là, tất nhiên, giá trị trả về từ system() là giá trị trả về từ việc thực thi chương trình, chứ không phải đầu ra từ chương trình. Nó có thể là cần thiết để chuyển hướng đầu ra vào một tập tin và đọc các tập tin, nếu bạn đang cố gắng để thu thập sản lượng của nó. – atk

+0

@atk: trong trường hợp đó, bạn có thể sử dụng một quy trình xử lý. – Ether

+1

không, trong trường hợp đó bạn sử dụng IPC :: Chạy hoặc IPC :: Cmd – ysth

3

Rất đơn giản. Kiểm tra biến thể hệ thống (LIST) của các cuộc gọi hệ thống.

system('bar', @ARGV); 

perldoc -f hệ thống

3

Trong bash:

exec bar "[email protected]" 

này giữ gìn khoảng cách trong các đối số. Mặc dù, chuyển hướng I/O không phải là một đối số trong ý nghĩa của thuật ngữ (nhưng chuyển hướng I/O được thực hiện cho lời gọi ban đầu sẽ tiếp tục tồn tại với lệnh 'bar' được gọi trừ khi bạn thay đổi nó).

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