Làm thế nào để chạy một lệnh nhiều lần, sử dụng bash shell?


153

Có cách nào để chạy một lệnh (ví dụ ps aux|grep someprocess) cho n lần không?

Cái gì đó như:

run -n 10  'ps aux|grep someprocess'

Tôi muốn sử dụng nó một cách tương tác, xin vui lòng không đăng kịch bản.

Cập nhật: Lý do tôi hỏi điều này là vì tôi làm việc trên rất nhiều máy và tôi không muốn nhập tất cả các tập lệnh được quảng cáo của mình, v.v. vào mỗi hộp để có cùng chức năng trên mọi máy.


Câu trả lời:


197

Tôi không nghĩ rằng một lệnh hoặc shell dựng sẵn cho điều này tồn tại, vì nó là một tập hợp con tầm thường của forvòng lặp shell Bourne được thiết kế để thực hiện và thực hiện một lệnh như thế này là khá đơn giản.

Để bắt đầu, bạn có thể sử dụng một forvòng lặp giả :

for i in `seq 10`; do command; done

Hoặc tương đương theo đề xuất của JimB, sử dụng nội dung Bash để tạo chuỗi:

for i in {1..10}; do command; done

Điều này lặp đi lặp lại mười lần thực thi commandmỗi lần - nó có thể là một đường ống hoặc một chuỗi các lệnh được phân tách bằng ;hoặc &&. Bạn có thể sử dụng $ibiến để biết bạn đang lặp lại.

Nếu bạn coi tập lệnh này là một tập lệnh và vì một số lý do không xác định (nhưng có lẽ hợp lệ) không thể chấp nhận được, bạn có thể triển khai nó dưới dạng một lệnh, có lẽ là một cái gì đó như thế này trên .bashrc (chưa được kiểm tra):

#function run
run() {
    number=$1
    shift
    for i in `seq $number`; do
      $@
    done
}

Sử dụng:

run 10 command

Thí dụ:

run 5 echo 'Hello World!'

16
@mahatmanich, Một vòng lặp không phải là một kịch bản. Không có gì ngăn cản bạn sử dụng cho ... tại một thiết bị đầu cuối tương tác.
Zoredache

3
Vâng, lớp lót ở trên là cách tiêu chuẩn để làm điều đó và nó khá đơn giản. Tại sao nó không tốt cho bạn? Có lẽ bạn đang hỏi sai câu hỏi? Mục tiêu chính của các kịch bản của bạn hoặc hành động của bạn mà bạn muốn lặp lại chúng một số lần là gì? Có lẽ có một giải pháp tốt hơn nếu chúng ta đặt vấn đề theo một cách khác.
Patkos Csaba

6
@mahatmanich - for bash tích hợp để lặp lại.
JimB

3
@Eduardo Ivanec - FYI, bash có phạm vi tích hợp sẵn như seq: {1..10}
JimB

1
Có vẻ như chuỗi khung sẵn có không hỗ trợ thay thế biến (xem stackoverflow.com/a/3737773/713554 ). Hàm bạn đã cho hoạt động hoàn hảo khi được đặt vào .bashrcnếu {1..$number} được trao đổi `seq $number`mặc dù.
Leo

29

ps aux | grep someprocesscó vẻ như bạn muốn xem các thay đổi của chương trình trong một thời gian cố định. Eduardo đã đưa ra một câu trả lời trả lời chính xác câu hỏi của bạn nhưng có một cách khác watch:

watch 'ps aux | grep someprocess'

Lưu ý rằng tôi đã đặt lệnh trong các dấu ngoặc đơn để tránh shell giải thích lệnh là "chạy xem ps aux" và dẫn kết quả qua grep someprocess. Một cách khác để thực hiện lệnh trước đó là:

watch ps aux \| grep someprocess

Theo mặc định, watchlàm mới cứ sau hai giây, có thể thay đổi bằng -ntùy chọn. Chẳng hạn, nếu muốn có khoảng thời gian là 1 giây:

watch -n 1 'ps aux | grep someprocess'

21

Chỉ để cho vui

pgrep ssh ;!!;!!;!!;!!;!!;!!

Ai đó có thể giải thích điều này xin vui lòng? Trông rất hấp dẫn.
Daniel Vartanov

4
; chỉ là dấu phân cách lệnh. !! phát lại lệnh cuối cùng trong bash. Vì vậy, điều này chạy 'pgrep ssh' và sau đó phát lại 6 lần.
Piotr Kukielka

Trong khi đó là hướng dẫn không phải là trực quan. Một lớp lót forcó vẻ là cách tốt nhất. Dù sao cũng cảm ơn câu trả lời.
erm3nda

1
Không phải cmd ;!!trên một dòng chỉ lặp lại lệnh đã nhập trước dòng hiện tại? Nó phải là hai historymục riêng biệt .
Joel Purra

thay thế ;bằng &&để dừng lại trên thất bại đầu tiên.
dùng881300

16

tương tự như các câu trả lời trước đó, nhưng không yêu cầu vòng lặp for:

seq 10 | xargs -I -- echo "hello"

đầu ra ống của seq đến xargs không có đối số hoặc tùy chọn


2
Điều này sẽ chỉ làm một thực thi echo "hello" 1 2 3 4 5 6 7 8 9 10. Bạn cần chạy xargs với -n 1một quy trình cho mỗi đầu vào (số) và với -P 10thực thi song song (10 quy trình song song). Kết thúc với seq 10 | xargs -n 1 -P 10 echo.
Alexander Klimetschek

16

Thử đi:

yes ls | head -n5 | bash

Điều này đòi hỏi lệnh phải được thực thi trong shell phụ, một hình phạt hiệu năng nhẹ. YMMV. Về cơ bản, bạn nhận được lệnh "có" để lặp lại chuỗi "ls" N lần; trong khi "head -n5" chấm dứt vòng lặp ở 5 lần lặp. Ống cuối cùng gửi lệnh đến vỏ bạn chọn.

Các cshshell giống như ngẫu nhiên có một repeatlệnh tích hợp. Bạn có thể sử dụng điều đó để thực thi lệnh của mình trong shell phụ bash!


5

Cách POSIX

http://pub.opengroup.org/onlinepub/9699919799/utilities/V3_chap02.html#tag_18_06_04_01

x=10
while [ $x -gt 0 ]; do
    command
    x=$(($x-1))
done

mà tất nhiên có thể được làm thành một lớp lót:

x=10; while [ $x -gt 0 ]; do command; x=$(($x-1)); done

và dường như là cách di động nhất, và do đó ít có khả năng khiến bạn cài đặt chương trình.

Sau đây là ít di động:

  • mở rộng cú đúp {1..10}: bash cụ thể và sẽ tạo ra một dòng lớn nếu đối số lớn
  • seq: GNU
  • yes: GNU

Và nếu bạn cảm thấy mệt mỏi với tính di động, hãy xem xét GNU parallel:

sudo apt-get install parallel
seq 100 | parallel echo {}

chạy các lệnh song song và có nhiều tùy chọn thú vị.

Xem thêm: https://stackoverflow.com/questions/169511/how-do-i-iterate-over-a-range-of-numbers-dained-by-variables-in-bash


GNU Parallel được xây dựng để rất di động. sh, zsh, kshbashđược hỗ trợ tốt trên hầu hết các nền tảng. csh, tcsh, fishcó một số hỗ trợ. Sử dụng, parallel --embedbạn thậm chí có thể xây dựng một tập lệnh có thể dễ dàng được chuyển sang một hệ thống khác chưa cài đặt GNU Parallel.
Ole Tange

2

Việc triển khai vỏ cá của runchức năng @ eduardo-ivanec ở trên

function run
  set number $argv[1]
  for i in (seq $number)
    eval $argv[2..-1]
  end
end

0

Đó sẽ là 'đồng hồ' - nên là một phần của hầu hết mọi hệ thống unix sử dụng Procps

Bạn có thể thấy fs thay đổi hoặc chuyển động thú vị khác trong một hệ thống. Ví dụ,

watch "df -hP | grep /tmp" 

Chỉ cần đặt các lệnh của bạn như là một đối số (xem man watch)


Đã có câu trả lời với đồng hồ ... xem ngay bên dưới ...
mahatmanich

0

Trên macOS bạn có thể sử dụng repeatlệnh.

repeat 10 ps aux | grep someprocess
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.