Pertanyaan Bagaimana cara menjalankan perintah beberapa kali, menggunakan bash shell?


Apakah ada cara untuk menjalankan perintah (mis. ps aux|grep someprocess) untuk n waktu?

Sesuatu seperti:

run -n 10  'ps aux|grep someprocess'

Saya ingin menggunakannya secara interaktif, tolong jangan posting skrip.

Update: Alasan saya menanyakan ini adalah, bahwa saya bekerja pada banyak mesin dan saya tidak ingin mengimpor semua skrip adap saya dll ke setiap kotak untuk mendapatkan fungsi yang sama di setiap mesin.


132
2018-05-24 15:55




Luar biasa bahwa jawabannya mendapatkan banyak upvote tanpa pertanyaan bahkan menerima satu. Mari kita ubah +1 itu :) - Lekensteyn
Terima kasih @Lekensteyn - mahatmanich
stackoverflow.com/questions/3737740/… - Ciro Santilli 新疆改造中心 六四事件 法轮功


Jawaban:


Saya tidak berpikir perintah atau shell builtin untuk ini ada, karena itu adalah bagian sepele dari apa Bourne shell for loop dirancang untuk dan mengimplementasikan perintah seperti ini sendiri karena itu cukup sederhana.

Sebagai permulaan Anda bisa menggunakan boneka for lingkaran:

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

Atau ekivalen sesuai saran Jimb, menggunakan Bash yang dibangun untuk menghasilkan rangkaian:

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

Ini mengulangi sepuluh kali eksekusi command setiap kali - dapat berupa pipa atau serangkaian perintah yang dipisahkan oleh ; atau &&. Anda dapat menggunakan $i variabel untuk mengetahui iterasi mana Anda berada.

Jika Anda menganggap ini sebagai liner satu skrip dan untuk beberapa alasan yang tidak ditentukan (tetapi mungkin sah) yang tidak dapat dibatalkan, Anda dapat mengimplementasikannya sebagai perintah, mungkin sesuatu seperti ini pada .bashrc Anda (belum diuji):

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

Pemakaian:

run 10 command

Contoh:

run 5 echo 'Hello World!'

170
2018-05-24 15:57



@mahatmanich, Lingkaran bukanlah skrip. Tidak ada yang menghalangi Anda untuk menggunakan ... di terminal interaktif. - Zoredache
Nah, satu-liner di atas adalah jenis cara standar untuk melakukannya dan itu cukup sederhana. Kenapa itu tidak baik untukmu? Mungkin Anda mengajukan pertanyaan yang salah? Apa tujuan utama skrip Anda atau tindakan Anda yang ingin Anda ulangi beberapa kali? Mungkin ada solusi yang lebih baik jika kita menempatkan masalah dengan cara yang berbeda. - Patkos Csaba
@mahatmanich - for  aku s bash built-in untuk iterasi. - JimB
@Eduardo Ivanec - FYI, bash memiliki berbagai built-in seperti seq: {1..10} - JimB
Tampaknya urutan bracket inbuilt tidak mendukung substitusi variabel (lihat stackoverflow.com/a/3737773/713554). Fungsi yang Anda berikan berfungsi dengan sempurna saat ditempatkan .bashrc jika {1..$number} ditukar `seq $number` meskipun. - Leo


ps aux | grep someprocess Sepertinya Anda ingin menonton perubahan program untuk waktu yang tetap. Eduardo memberikan jawaban yang menjawab pertanyaan Anda dengan tepat tetapi ada alternatif: watch:

watch 'ps aux | grep someprocess'

Perhatikan bahwa saya telah menempatkan perintah dalam tanda kutip tunggal untuk menghindari shell dari menafsirkan perintah sebagai "menjalankan menonton ps aux" dan pipa hasilnya melalui grep someprocess. Cara lain untuk melakukan perintah sebelumnya adalah:

watch ps aux \| grep someprocess

Secara default, watch menyegarkan setiap dua detik, yang dapat diubah menggunakan -n pilihan. Misalnya, jika ingin memiliki selang waktu 1 detik:

watch -n 1 'ps aux | grep someprocess'

29
2018-05-26 15:07



Ya ini bekerja seperti pesona. - Jānis Gruzis


Hanya untuk bersenang-senang

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

21
2018-06-27 13:04



Bisakah seseorang menjelaskan ini? Terlihat sangat menarik. - Daniel Vartanov
; hanya pemisah perintah. !! ulangi perintah terakhir di bash. Jadi ini jalankan 'pgrep ssh' dan kemudian ulangi sebanyak 6 kali. - Piotr Kukielka
Sedangkan yang bersifat instruktif tidak vry intuitif. Satu-liner for sepertinya cara terbaik. Pokoknya terima kasih atas jawabannya. - erm3nda
Biasa cmd ;!! pada satu baris cukup ulangi perintah yang dimasukkan sebelum garis saat ini? Itu harus menjadi dua terpisah history entri. - Joel Purra


Coba ini:

yes ls | head -n5 | bash

Ini membutuhkan perintah untuk dieksekusi di sub-shell, penalti kinerja sedikit. YMMV. Pada dasarnya, Anda mendapatkan perintah "ya" untuk mengulang string "ls" N kali; sementara "head -n5" menghentikan pengulangan pada 5 pengulangan. Pipa terakhir mengirimkan perintah ke shell pilihan Anda.

Kebetulan csh-seperti shell memiliki built-in repeat perintah. Anda bisa menggunakannya untuk mengeksekusi perintah Anda dalam bash sub-shell!


14
2018-01-31 00:04





mirip dengan balasan sebelumnya, tetapi tidak memerlukan pengulangan:

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

output pipa dari seq ke xargs tanpa argumen atau opsi


11
2017-11-18 14:36



Ini hanya akan melakukan satu eksekusi echo "hello" 1 2 3 4 5 6 7 8 9 10. Anda perlu menjalankan xargs dengan -n 1 untuk satu proses untuk setiap input (angka) dan dengan -P 10 untuk eksekusi paralel (10 proses paralel). Berakhir dengan seq 10 | xargs -n 1 -P 10 echo. - Alexander Klimetschek


Cara POSIX

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_04_01

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

yang tentu saja bisa dibuat menjadi satu liner:

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

dan tampaknya menjadi cara paling portabel, dan dengan demikian cenderung membuat Anda menginstal program.

Berikut ini kurang portabel:

  • brace ekspansi {1..10}: bash spesifik, dan akan menghasilkan garis besar jika argumennya besar
  • seq: GNU
  • yes: GNU

Dan jika Anda bosan dengan portabilitas, pertimbangkan GNU parallel:

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

yang menjalankan perintah secara paralel dan memiliki banyak opsi keren.

Lihat juga: https://stackoverflow.com/questions/169511/how-do-i-iterate-over-a-range-of-numbers-defined-by-variables-in-bash


4
2018-06-15 09:39





Implementasi fish shell @ eduardo-ivanec's run fungsi atas

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

2
2018-06-20 18:44





Itu akan menjadi 'jam' - seharusnya menjadi bagian dari hampir semua sistem unix menggunakan procps

Anda dapat melihat perubahan fs atau gerakan menarik dalam suatu sistem. Sebagai contoh,

watch "df -hP | grep /tmp" 

Taruh saja perintah Anda sebagai argumen (lihat man watch)


0



Sudah ada jawaban dengan jam tangan ... lihat tepat di bawah ... - mahatmanich