2013-07-16 41 views
8

Tôi đã đưa ra một kịch bản tuyệt vời sẽ tạo ra kết quả mà tôi cần, nhưng nó chỉ hiển thị trên màn hình, vì vậy tôi phải sao chép, sau đó dán vào các lệnh để làm cho chúng thực thi. Đây là phiên bản rút gọn của kịch bản của tôi:Tôi có thể sử dụng ECHO để thực thi các lệnh không?

#!/bin/bash 
runc=/etc/csf/csf.pl -d 
for IP in `tail -400 iptext.txt` 
do 
cc=`geoiplookup $IP` 
echo -e $runc $IP $cc | grep Algeria 
echo -e $runc $IP $cc | grep Argentina 
echo -e $runc $IP $cc | grep Armenia 
echo -e $runc $IP $cc | grep Azerbaijan 
echo -e $runc $IP $cc | grep Bolivia 
echo -e $runc $IP $cc | grep Brazil 
done 

Được rồi, vì vậy nó vòng qua danh sách các địa chỉ IP trong iptext.txt, sau đó thực hiện một tra cứu geoIP trên mỗi, if (trong ví dụ này) có hai geoIP phù hợp trong danh sách, hãy nói cho Armenia và Brazil, tôi sẽ thấy kết quả như thế này để các cửa sổ shell:

/etc/csf/csf.pl -d 46.162.242.17 GeoIP Country Edition: AM, Armenia 
/etc/csf/csf.pl -d 200.147.38.50 GeoIP Country Edition: BR, Brazil 

này là rất tốt, nhưng tôi muốn nhiều hơn chỉ là đầu ra, tôi thực sự muốn lệnh /etc/csf/csf.pl -d để chạy, và chặn (chỉ và duy nhất) IP trong các dòng khớp với tên quốc gia, trong danh sách.

Tôi đã thử nhiều thứ khác nhau với kiến ​​thức giới hạn về kịch bản lệnh shell, nhưng cho đến nay, không có gì có vẻ hiệu quả. Vì vậy, có một số tùy chọn cho ECHO tôi đang thiếu mà thực sự sẽ chạy lệnh thay vì chỉ in ra dòng?

+0

Tôi có rollback bao gồm bạn một câu trả lời trong câu hỏi của chính nó. Vui lòng đăng câu trả lời của riêng bạn hoặc phê duyệt câu trả lời hiện có. Lưu ý rằng giải pháp của bạn gần giống với câu trả lời của Flo Doe. –

Trả lời

8

Một cách đơn giản mà sẽ không cần sửa đổi tập lệnh của bạn sẽ là đường dẫn đầu ra của lệnh sang một thể hiện bash khác. Như thế này:

yourscript | bash - 

- cho bash rằng cần đọc lệnh từ stdin.


Tuy nhiên, nếu bạn không tìm kiếm giải pháp nhanh, bạn cũng có thể tạo và thực thi lệnh. Như thế này:

cmd="ls" 
if [ "foo" != "bar" ] ; then 
    cmd="$cmd -a" 
then 

# ... and so on 

# now execute it: 
$cmd 
+1

Bạn cũng có thể đặt đường vòng 'for' thành' bash': 'cho x trong ...; làm ...; đã hoàn thành | bash -' –

+0

@glennjackman Tôi đã không chắc chắn và quá lười biếng để kiểm tra;) ... đường ống đầu ra của vòng lặp âm thanh như giải pháp tốt nhất cho tôi. cám ơn – hek2mgl

7

Bạn có thể sử dụng eval để thực hiện một chuỗi:

eval $cmdstring 
0

Sử dụng grep -E và một mô hình thay vì:

$runc $IP $cc | grep -E 'Algeria|Argentina|...' 

Giải thích: echo sẽ in lệnh nhưng không thực hiện nó. Chỉ cần bỏ qua nó để thực sự thực hiện lệnh.

Và thay vì chạy tập lệnh 5 lần, hãy sử dụng grep để tìm kiếm bất kỳ trong số năm mẫu cùng một lúc.

Và bạn nên sử dụng

cc=$(geoiplookup $IP) 

thay vì backticks; nó an toàn hơn.

5

Có một bash nội trang eval, điều này thực thi các lệnh giống như chúng được nhập vào trình bao của bạn. Ví dụ: trong tập lệnh của bạn, bạn có thể thực hiện các thao tác sau:

eval $(echo -e $runc $IP $cc | grep Algeria) 

Điều này sẽ xử lý tiếng vọng của bạn trong một vỏ và đầu ra sẽ được thực hiện như bạn đã gõ vào vỏ của bạn, sau đó nhập.

Xem dưới đây exerpt từ bash dẫn sử dụng:

eval [arg ...] Các arg được đọc và ghép lại với nhau thành một lệnh duy nhất. Lệnh này sau đó được đọc và thực thi bởi trình bao, và trạng thái thoát của nó được trả về là giá trị của eval. Nếu không có args, hoặc chỉ đối số null, eval trả về 0.

0
echo `pwd` 

trên công trình lệnh cho tôi.

1

Chỉ cần đặt lệnh của bạn vào ngoặc như thế này:

echo $(ls)