2009-04-06 23 views
6

giả sử bạn có một kịch bản perl "foobar.pl" mà in ra sau để thiết bị xuất chuẩnchạy đầu ra của một kịch bản như một lệnh bash độc

date -R 

và bạn muốn chạy bất cứ điều gì mà kết quả đầu ra perl script như một lệnh bash độc lập (đừng lo lắng về các vấn đề bảo mật vì điều này đang chạy trong một môi trường đáng tin cậy).

Làm thế nào để bạn nhận được bash để nhận ra đây là một lệnh độc lập?

Tôi đã thử sử dụng xarg, nhưng dường như chỉ muốn vượt qua đối số chỉ cho lệnh được xác định trước.

Tôi muốn tập lệnh perl có thể xuất bất kỳ lệnh tùy ý nào.

$command = 'date -R' 
system($command); ## in the perl script 

ở trên không làm việc vì tôi muốn nó chạy trong một môi trường Cygwin hiện ...

foobar.pl | xargs bash -i {} 

ở trên không làm việc vì bash vẻ là đang chạy một quá trình mới và do đó khởi tạo và cài đặt từ bash_profile không được khởi tạo.

Trả lời

4

Xấu:

`perl foo.pl` 
$(perl foo.pl) 

Tại sao điều này là xấu? Vì rất nhiều lý do; đáng chú ý nhất:

  • Từ khóa: Những gì bạn đang thực hiện ở đây là lấy đầu ra của tập lệnh perl, chia thành các khối bất cứ nơi nào có dấu cách, tab hoặc dòng mới và lấy những đoạn đó làm đối số cho đoạn đầu tiên là lệnh để chạy. Trong những trường hợp cực kỳ đơn giản như $(echo 'date +%s') nó có thể hoạt động; nhưng đó chỉ là một đại diện thực sự xấu về những gì bạn đang thực sự làm ở đây.
  • Bạn không thể trích dẫn hoặc sử dụng bất kỳ tính năng nào khác của vỏ bọc như mở rộng thông số, từ khóa bash, v.v.

Tốt, nhưng bất tiện:

perl foo.pl > mytmpfile; bash mytmpfile 

Tạo một tập tin tạm thời để đưa ra kịch bản perl của bạn vào và sau đó chạy mà với việc bash, nhưng đó là bất tiện khi bạn cần phải tạo ra (và sạch lên!) tệp tạm thời của bạn và đặt nó ở vị trí có thể ghi được (và an toàn!).

Cũng nhớ không sử dụng . hoặc source để thực thi tệp tạm thời trừ khi bạn thực sự có ý định chạy tất cả trong vỏ đang hoạt động. Hơn nữa, khi bạn sử dụng . hoặc source, bạn sẽ không thể xóa tệp tạm thời của bạn một cách đáng tin cậy sau đó.

Có lẽ giải pháp tốt nhất:

perl foo.pl | bash 

này là khá an toàn toàn diện ("an toàn" trong bối cảnh, nhất là lỗi dễ xảy ra) giả định perl của bạn kết quả đầu ra kịch bản đúng cú pháp bash, tất nhiên .

Alternatives mà khá nhiều điều tương tự:

bash < <(perl foo.pl) 
bash <(perl foo.pl) 
+0

bash <($ OUTPUT) là những gì tôi đang tìm kiếm. Nó làm cho một sự khác biệt HUGE với đường ống như bạn vẫn có sự kiểm soát của nó - cho đầu vào. – yclian

3

Hãy thử:

foobar.pl | bash 
+0

xuất khẩu FOO = 'foobar.pl '; $ FOO – ojblass

0

Tôi không nghĩ rằng đây là chính xác những gì bạn đang tìm kiếm, nhưng những gì nó tôi đã có :-)

perl foo.pl > /tmp/$$.script; bash /tmp/$$.script; rm /tmp/$$.script 

Chúc may mắn!

5
`foobar.pl` 
+0

+1 để đơn giản. :) –

4

Với file perl:

print "date"; 

lệnh bash sau đây sẽ làm điều đó.

> $(perl qq.pl) 
Mon Apr 6 11:02:07 WAST 2009 

Nhưng điều đó được chạy trong một trình bao riêng biệt. Nếu bạn thực sự muốn gọi nó trong bối cảnh của hiện vỏ, làm điều này:

$ perl qq.pl >/tmp/qq.$$ ; . /tmp/qq.$$ ; rm -f /tmp/qq.$$ 
Mon Apr 6 11:04:59 WAST 2009 
+0

Trong trường hợp $(), lệnh "perl qq.pl" được chạy trong một trình bao riêng biệt, nhưng lệnh được trả về bởi "date", được chạy trong trình bao hiện tại, đó là, tôi nghĩ, anh ấy muốn. –

+0

Bạn không nên sử dụng '.' hoặc' source' để chạy các lệnh. Bạn không bao giờ biết kịch bản sẽ làm gì với shell đang chạy của bạn; có nghĩa là bạn không thể dựa vào thực tế là bạn thậm chí sẽ có cơ hội để làm sạch tệp tạm thời của bạn đúng cách. Đặt dọn dẹp trong một cái bẫy trên EXIT có thể giúp với điều đó. – lhunath

+0

@lhunath, bạn đã không đọc câu hỏi chưa? Quoth the quạ "đừng lo lắng về vấn đề bảo mật vì điều này đang chạy trong một môi trường đáng tin cậy". Tôi lấy nó để có nghĩa là đầu ra của kịch bản Perl đã được kiểm soát. Và việc sử dụng "." đã được cụ thể để đáp ứng yêu cầu nó không bắt đầu một quá trình mới. – paxdiablo

0

Hãy thử với mở ($ fh, "- |", $ arg1, arg2 $)

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