2010-08-12 30 views
7

Tôi đã cố gắng chạy các lệnh bằng cách sử dụng đường ống.Làm thế nào để chạy các lệnh script từ các biến?

Basic:

single="ls -l" 
$single 

trong đó hoạt động như mong đợi

Ống:

multi="ls -l | grep e" 
$multi 
ls: |: No such file or directory 
ls: grep: No such file or directory 
ls: e: No such file or directory 

... không ngạc nhiên

bash < $multi 

$multi: ambiguous redirect 
.210

tiếp theo thử

bash $multi 
/bin/ls: /bin/ls: cannot execute binary file 

Chỉ

echo $multi > tmp.sh 
bash tmp.sh 

làm việc.

Có cách nào để thực thi các lệnh phức tạp hơn mà không cần tạo tập lệnh để thực thi không?

+0

Xem [BashFAQ/050] (http://mywiki.wooledge.org/BashFAQ/050). –

Trả lời

11

Bạn đang thể hiện sự khác biệt giữa vỏ và hạt nhân.

"ls -l" có thể thực hiện được bằng lệnh gọi hàm execve(). Bạn có thể man execve để biết chi tiết, nhưng đó có thể là quá nhiều chi tiết cho bạn.

"ls -l | grep e" cần giải thích vỏ để thiết lập đường ống. Không sử dụng trình bao, '|' ký tự được đưa vào execve() như một đối số cho ls. Đây là lý do tại sao bạn thấy lỗi "Không có tệp hoặc thư mục" như vậy.

Giải pháp:

cmd="ls -l | grep e" 
bash -c "$cmd" 
+0

Cảm ơn, bất kỳ ý tưởng nào tại sao "bash -c" in kết quả đầu ra trong một dòng? Tôi muốn có cùng một đầu ra như được nhập bằng tay tại dòng lệnh. – stacker

+0

@stacker Tôi không nghĩ đó là sự thật.Tôi nhận được kết quả tương tự như ở dòng lệnh. Có lẽ grep của bạn chỉ trả về một dòng? – bukzor

+0

Điều này xảy ra vì tôi quên gửi kèm theo dấu ngoặc kép. – stacker

-3

khi bạn muốn chạy lệnh với đường ống, chỉ cần chạy nó. Đừng bao giờ đặt lệnh vào một biến và cố gắng chạy nó. Đơn giản chỉ cần thực hiện nó

ls -l |grep

Nếu bạn muốn chụp đầu ra, sử dụng $()

var=$(ls -l |grep ..)

+0

Lệnh đến từ một máy chủ khác và nên bị xử lý trên máy đích. Vì vậy, nó không thể được mã hóa cứng. – stacker

+0

xem http://mywiki.wooledge.org/BashFAQ/050 – ghostdog74

0

Bạn cần một heredoc để làm điều này một cách chính xác. Trong câu trả lời cho POSIX compliant way to see if a function is defined in an sh script, tôi đã nêu chi tiết cách đọc một tập lệnh thành một biến, phân tích cú pháp theo chương trình để biết thông tin và/hoặc sửa đổi nó khi cần thiết, sau đó thực thi nó từ một tập lệnh hoặc hàm shell khác. Đó là cơ bản những gì bạn đang cố gắng để làm, và heredoc làm cho nó có bởi vì nó cung cấp một mô tả file:

% multi='ls -l | grep e' 
% sh <<_EOF_ 
> ${multi} 
> _EOF_ 
< desired output > 

rằng sẽ giải quyết trường hợp ví dụ đơn giản của bạn. Xem câu trả lời khác của tôi để biết thêm.

-Mike

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