Setiap sysadmin mungkin memiliki beberapa keterampilan yang telah mereka pelajari selama bertahun-tahun yang dapat mereka tunjukkan dan katakan, "Itu mengubah dunia saya." Keterampilan itu, atau sedikit informasi itu, atau teknik itu baru saja mengubah cara saya melakukan sesuatu. Bagi banyak dari kita, hal itu berulang di Bas. Ada pendekatan lain untuk otomatisasi yang tentunya lebih kuat atau terukur. Kebanyakan dari mereka tidak sebanding dengan kesederhanaan dan kegunaan siap pakai dari for
lingkaran, meskipun.
Jika Anda ingin mengotomatiskan konfigurasi ribuan sistem, Anda mungkin harus menggunakan Ansible. Namun, jika Anda mencoba mengganti nama seribu file, atau menjalankan perintah yang sama beberapa kali, maka for
loop jelas merupakan alat yang tepat untuk pekerjaan itu.
[ Anda mungkin juga menyukai: Menguasai loop dengan template Jinja di Ansible ]
Jika Anda sudah memiliki latar belakang pemrograman atau skrip, Anda mungkin sudah familiar dengan for
loop lakukan. Jika tidak, saya akan mencoba menguraikannya dalam bahasa Inggris yang sederhana untuk Anda.
Konsep dasarnya adalah: UNTUK satu set item tertentu, LAKUKAN sesuatu.
Kumpulan item yang diberikan dapat berupa kumpulan objek literal atau apa pun yang dapat diekstrapolasikan oleh Bash ke daftar. Misalnya, teks yang diambil dari file, output dari perintah Bash lain, atau parameter yang diteruskan melalui baris perintah. Mengubah struktur loop ini menjadi skrip Bash juga sepele. Dalam artikel ini, kami menunjukkan beberapa contoh bagaimana for
loop dapat membuat Anda terlihat seperti pahlawan baris perintah, lalu kami mengambil beberapa contoh tersebut dan memasukkannya ke dalam skrip Bash yang lebih terstruktur.
Struktur dasar perulangan for
Pertama, mari kita bicara tentang struktur dasar for
loop, dan kemudian kita akan masuk ke beberapa contoh.
Sintaks dasar dari for
lingkarannya adalah:
for <variable name> in <a list of items>;do <some command> $<variable name>;done;
Nama variabel akan menjadi variabel yang Anda tentukan di do
bagian dan akan berisi item dalam lingkaran yang Anda gunakan.
Daftar item dapat berupa apa saja yang mengembalikan spasi atau daftar yang dipisahkan baris baru.
Ini contohnya:
$ for name in joey suzy bobby;do echo $name;done
Itu sesederhana yang didapat dan tidak banyak yang terjadi di sana, tetapi ini membantu Anda memulai. Variabel $name akan berisi item dalam daftar tempat loop sedang beroperasi, dan setelah perintah (atau perintah) di do
bagian dilakukan, loop akan pindah ke item berikutnya. Anda juga dapat melakukan lebih dari satu tindakan per loop. Apa pun di antara do
dan done
akan dieksekusi. Perintah baru hanya perlu ;
membatasi mereka.
$ for name in joey suzy bobby; do echo first $name;echo second $name;done;
first joey
second joey
first suzy
second suzy
first bobby
second bobby
Sekarang untuk beberapa yang nyata contoh.
Mengganti nama file
Loop ini mengambil output dari perintah Bash ls *.pdf
dan melakukan tindakan pada setiap nama file yang dikembalikan. Dalam hal ini, kami menambahkan tanggal hari ini di akhir nama file (tetapi sebelum ekstensi file).
for i in $(ls *.pdf); do
mv $i $(basename $i .pdf)_$(date +%Y%m%d).pdf
done
Sebagai ilustrasi, jalankan loop ini dalam direktori yang berisi file-file ini:
file1.pdf
file2.pdf
...
fileN.pdf
File akan diganti namanya seperti ini:
file1_20210210.pdf
file2_20210210.pdf
...
fileN_20210210.pdf
Dalam direktori dengan ratusan file, loop ini menghemat banyak waktu Anda dalam mengganti nama semuanya.
Mengekstrapolasi daftar item
Bayangkan Anda memiliki file yang ingin Anda scp
ke beberapa server. Ingat bahwa Anda dapat menggabungkan for
loop dengan fitur Bash lainnya, seperti ekspansi shell, yang memungkinkan Bash untuk memperluas daftar item yang ada dalam rangkaian. Ini dapat bekerja untuk huruf dan angka. Misalnya:
$ echo {0..10}
0 1 2 3 4 5 6 7 8 9 10
Dengan asumsi server Anda diberi nama dalam semacam pola seperti, web0 , web1 , web2 , web3 , Anda dapat meminta Bash mengulangi rangkaian angka seperti ini:
$ for i in web{0..10};do scp somefile.txt ${i}:;done;
Ini akan diulang melalui web0 , web1 , web2 , web3 , dan seterusnya, menjalankan perintah Anda pada setiap item.
Anda juga dapat menentukan beberapa iterasi. Misalnya:
$ for i in web{0..10} db{0..2} balance_{a..c};do echo $i;done
web0
web1
web2
web3
web4
web5
web6
web7
web8
web9
web10
db0
db1
db2
balance_a
balance_b
balance_c
Anda juga dapat menggabungkan iterasi. Bayangkan Anda memiliki dua pusat data, satu di Amerika Serikat, satu lagi di Kanada, dan konvensi penamaan server mengidentifikasi pusat data tempat tinggal pasangan HA server. Misalnya, web-us-0 akan menjadi server web pertama di pusat data AS, sementara web-ca-0 akan menjadi web 0 rekanan di pusat data CA. Untuk mengeksekusi sesuatu di kedua sistem, Anda dapat menggunakan urutan seperti ini:
$ for i in web-{us,ca}-{0..3};do echo $i;done
web-us-0
web-us-1
web-us-2
web-us-3
web-ca-0
web-ca-1
web-ca-2
web-ca-3
Jika nama server Anda tidak mudah untuk diulang, Anda dapat memberikan daftar nama ke for
lingkaran:
$ cat somelist
first_item
middle_things
foo
bar
baz
last_item
$ for i in `cat somelist`;do echo "ITEM: $i";done
ITEM: first_item
ITEM: middle_things
ITEM: foo
ITEM: bar
ITEM: baz
ITEM: last_item
Bersarang
Anda juga dapat menggabungkan beberapa ide ini untuk kasus penggunaan yang lebih kompleks. Misalnya, bayangkan Anda ingin menyalin daftar file ke server web Anda yang mengikuti konvensi penamaan bernomor yang Anda gunakan pada contoh sebelumnya.
Anda dapat melakukannya dengan mengulangi daftar kedua berdasarkan daftar pertama Anda melalui loop bersarang. Ini menjadi agak sulit untuk diikuti ketika Anda melakukannya sebagai one-liner, tetapi itu pasti bisa dilakukan. for
bersarang Anda loop dieksekusi pada setiap iterasi for
induknya lingkaran. Pastikan untuk menentukan nama variabel yang berbeda untuk setiap loop.
Untuk menyalin daftar file file1.txt, file2.txt, dan file3.txt ke server web, gunakan loop bersarang ini:
$ for i in file{1..3};do for x in web{0..3};do echo "Copying $i to server $x"; scp $i $x; done; done
Copying file1 to server web0
Copying file1 to server web1
Copying file1 to server web2
Copying file1 to server web3
Copying file2 to server web0
Copying file2 to server web1
Copying file2 to server web2
Copying file2 to server web3
Copying file3 to server web0
Copying file3 to server web1
Copying file3 to server web2
Copying file3 to server web3
Penggantian nama yang lebih kreatif
Mungkin ada cara lain untuk menyelesaikannya, tetapi ingat, ini hanya contoh hal yang bisa Anda lakukan. lakukan dengan for
lingkaran. Bagaimana jika Anda memiliki segunung file bernama seperti FILE002.txt , dan Anda ingin mengganti FILE dengan sesuatu seperti TEXT . Ingatlah bahwa selain Bash itu sendiri, Anda juga memiliki alat open source lain yang Anda inginkan, seperti sed
, grep
, dan banyak lagi. Anda dapat menggabungkan alat tersebut dengan for
lingkaran, seperti ini:
$ ls FILE*.txt
FILE0.txt FILE10.txt FILE1.txt FILE2.txt FILE3.txt FILE4.txt FILE5.txt FILE6.txt FILE7.txt FILE8.txt FILE9.txt
$ for i in $(ls FILE*.txt);do mv $i `echo $i | sed s/FILE/TEXT/`;done
$ ls FILE*.txt
ls: cannot access 'FILE*.txt': No such file or directory
$ ls TEXT*.txt
TEXT0.txt TEXT10.txt TEXT1.txt TEXT2.txt TEXT3.txt TEXT4.txt TEXT5.txt TEXT6.txt TEXT7.txt TEXT8.txt TEXT9.txt
Menambahkan for loop ke skrip Bash
Menjalankan for
loop langsung pada baris perintah sangat bagus dan menghemat banyak waktu untuk beberapa tugas. Selain itu, Anda dapat menyertakan for
loop sebagai bagian dari skrip Bash Anda untuk meningkatkan daya, keterbacaan, dan fleksibilitas.
Misalnya, Anda dapat menambahkan contoh loop bersarang ke skrip Bash untuk meningkatkan keterbacaannya, seperti ini:
$ vim copy_web_files.sh
# !/bin/bash
for i in file{1..3};do
for x in web{0..3};do
echo "Copying $i to server $x"
scp $i $x
done
done
Saat Anda menyimpan dan menjalankan skrip ini, hasilnya sama dengan menjalankan contoh loop bersarang di atas, tetapi lebih mudah dibaca, ditambah lebih mudah untuk mengubah dan memeliharanya.
$ bash copy_web_files.sh
Copying file1 to server web0
Copying file1 to server web1
... TRUNCATED ...
Copying file3 to server web3
Anda juga dapat meningkatkan fleksibilitas dan penggunaan kembali for
loop dengan memasukkannya ke dalam skrip Bash yang memungkinkan input parameter. Misalnya, untuk mengganti nama file seperti contoh Penggantian nama yang lebih kreatif di atas memungkinkan pengguna untuk menentukan akhiran nama, gunakan skrip ini:
$ vim rename_files.sh
# !/bin/bash
source_prefix=$1
suffix=$2
destination_prefix=$3
for i in $(ls ${source_prefix}*.${suffix});do
mv $i $(echo $i | sed s/${source_prefix}/${destination_prefix}/)
done
Dalam skrip ini, pengguna menyediakan awalan file sumber sebagai parameter pertama, akhiran file sebagai parameter kedua, dan awalan baru sebagai parameter ketiga. Misalnya, untuk mengganti nama semua file yang dimulai dengan FILE , dari jenis .txt ke TEXT , jalankan script seperti ini :
$ ls FILE*.txt
FILE0.txt FILE10.txt FILE1.txt FILE2.txt FILE3.txt FILE4.txt FILE5.txt FILE6.txt FILE7.txt FILE8.txt FILE9.txt
$ bash rename_files.sh FILE txt TEXT
$ ls TEXT*.txt
TEXT0.txt TEXT10.txt TEXT1.txt TEXT2.txt TEXT3.txt TEXT4.txt TEXT5.txt TEXT6.txt TEXT7.txt TEXT8.txt TEXT9.txt
Ini mirip dengan contoh aslinya, tetapi sekarang pengguna Anda dapat menentukan parameter lain untuk mengubah perilaku skrip. Misalnya, untuk mengganti nama semua file sekarang dimulai dengan TEXT ke BARU , gunakan yang berikut ini:
$ bash rename_files.sh TEXT txt NEW
$ ls NEW*.txt
NEW0.txt NEW10.txt NEW1.txt NEW2.txt NEW3.txt NEW4.txt NEW5.txt NEW6.txt NEW7.txt NEW8.txt NEW9.txt
[ Kursus gratis untuk Anda:Tinjauan Teknis Virtualisasi dan Migrasi Infrastruktur. ]
Kesimpulan
Mudah-mudahan, contoh-contoh ini telah menunjukkan kekuatan for
loop di baris perintah Bash. Anda benar-benar dapat menghemat banyak waktu dan melakukan tugas dengan cara yang tidak terlalu rawan kesalahan dengan loop. Hati-hati. Loop Anda akan melakukan apa yang Anda minta, bahkan jika Anda meminta mereka melakukan sesuatu yang merusak secara tidak sengaja, seperti membuat (atau menghapus) volume logis atau disk virtual.
Kami berharap Bash for
loop mengubah dunia Anda dengan cara yang sama seperti mereka mengubah dunia kita.