Ekspansi Bash Shell: Ekspansi Brace, Ekspansi Parameter, dan lainnya

Pada artikel ini kita akan membahas semua fitur dasar ekspansi Bash Shell. Beberapa ekspansi yang paling kompleks dan menarik adalah Ekspansi Brace dan Ekspansi Parameter yang memiliki banyak fitur dan opsi yang kuat tetapi hanya dikuasai dari waktu ke waktu oleh programmer BASH dan pengembang linux. Pemisahan Kata juga cukup menarik dan terkadang diabaikan. Nama file, Ekspansi Aritmatika, dan Substitusi variabel sudah dikenal luas. Kami akan membahas banyak topik dan menunjukkan contoh perintah dan sintaks yang paling berguna untuk setiap sintaks. Jadi mari kita mulai.

Lingkungan

Untuk menguji semua fitur ekspansi shell bash, kita perlu memastikan bahwa kita menjalankan versi bash terbaru. Di bawah ini adalah informasi sistem untuk artikel ini. Tes dalam artikel ini berjalan di Ubuntu 19.10 seperti yang ditunjukkan di bawah ini.

$ uname -a
Linux instance-1 5.3.0-1014-gcp #15-Ubuntu SMP Tue Mar 3 04:14:57
UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

Versi bash untuk pengujian ini adalah bash versi 5, yang cukup baru. Versi bash yang lebih lama tidak memiliki banyak fitur.

$ bash --version
GNU bash, version 5.0.3(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

Pergantian Perintah

Substitusi perintah memungkinkan menjalankan satu atau beberapa perintah dan menangkap output dan tindakan dari perintah tersebut dan memasukkannya ke dalam perintah lain semua dalam satu baris atau kurang dari menjalankan semua perintah secara terpisah. Substitusi Perintah memiliki dua sintaks; sintaks yang lebih populer adalah sintaks backtick di mana perintah yang akan dieksekusi diapit oleh dua backquotes, atau backtick. Sintaks lain yang sama kuatnya menyertakan perintah dalam sintaks $() dan output dapat digunakan dari ekspansi baru itu. Mari kita lihat beberapa contoh Substitusi Perintah di bawah ini.

Substitusi perintah sederhana menggunakan sintaks $() untuk menjalankan perintah tanggal.

$ echo $(date)
Wed Mar 18 01:42:46 UTC 2020

Substitusi perintah sederhana menggunakan sintaks backtick untuk menjalankan perintah tanggal.

$ echo `date`
Wed Mar 18 01:43:17 UTC 2020

Menggunakan operator stdin di awal sintaks substitusi perintah adalah cara yang bagus untuk membaca teks file ke dalam variabel dan menggunakannya dalam perintah di shell seperti di bawah ini.

$ echo "hello world" > mytext
$ echo $(< mytext)
hello world

Membaca file menjadi variabel yang akan digunakan dalam perintah menggunakan perintah cat dan Substitusi Perintah.

$ echo "hello world" > mytext
$ echo $(cat mytext)
hello world

Sama seperti di atas, baca file dan gunakan di Substitusi Perintah menggunakan backticks dan perintah cat.

$ echo "hello world" > mytext
$ echo `cat mytext`
hello world

Gabungkan Substitusi Perintah yang disematkan dengan Substitusi Perintah lain menggunakan $() dan backtick bersama-sama

$ echo `echo $(date) |cut -d " " -f 1` > myfile
$ cat myfile
Wed

Substitusi Perintah Tertanam di dalam yang lain menggunakan dua operasi sintaks $()

$ echo "today is $(echo $(date) |cut -d " " -f 1)" > myfile
$ cat myfile
today is Wed

Gunakan output dari suatu perintah sebagai argumen ke dalam perintah lain, dengan sintaks backtick. Kami akan mendapatkan daftar file dengan menjalankan cat yang berisi satu file per baris dan kemudian meneruskannya ke perintah rm yang akan menghapus setiap file

$ touch one; touch two
$ echo one > myfiles; echo two >> myfiles
$ rm `cat myfiles`

Sama seperti di atas tetapi dengan sintaks $(), berikan output perintah dari cat ke perintah rm untuk menghapus file.

$ touch one; touch two
$ echo one > myfiles; echo two >> myfiles
$ rm $(cat myfiles)

Simpan output dari perintah cat ke dalam variabel dan kemudian ulangi variabel sehingga Anda dapat melihat dengan lebih jelas apa yang terjadi.

$ touch one; touch two
$ echo one > myfiles; echo two >> myfiles
$ MYFILES=$(cat myfiles)
$ for f in $MYFILES; do echo $f; rm $f; done
one
two

Sama seperti di atas tetapi gunakan sintaks backticks untuk menjalankan perintah cat dan menyimpan output dalam variabel dan kemudian mengulang file ke dalam variabel.

$ touch one; touch two
$ echo one > myfiles; echo two >> myfiles
$ MYFILES=`cat myfiles`
$ for f in $MYFILES; do echo $f; rm $f; done
one
two

Gunakan Substitusi Perintah dengan operator stdin untuk membaca file baris demi baris ke dalam variabel dan kemudian mengulang melalui variabel kata penutup

$ touch one; touch two
$ echo one > myfiles; echo two >> myfiles
$ MYFILES=$(< myfiles)
$ for f in $MYFILES; do echo $f; rm $f; done
one
two

Substitusi Proses

Substitusi Proses adalah fitur bash yang terdokumentasi; itu cukup samar menurut saya. Sebenarnya saya belum menemukan banyak kasus useran yang bagus untuk direkomendasikan untuk itu. Salah satu contoh disertakan di sini untuk kelengkapan di mana kita menggunakan Substitusi Proses untuk mendapatkan output dari suatu perintah dan kemudian menggunakannya untuk perintah lain. Kami akan mencetak daftar file dalam urutan terbalik dengan perintah sort dalam contoh ini setelah mengambil file dari perintah ls.

Substitusi Variabel

Substitusi Variabel adalah apa yang Anda dapat mempertimbangkan useran dasar variabel dan mengganti nilai variabel ketika direferensikan. Ini cukup intuitif, beberapa contoh disediakan di bawah ini.

Penugasan dan useran variabel sederhana di mana kami memasukkan string ke dalam variabel X dan kemudian mencetaknya ke stdout

$ X=12345
$ echo $X
12345

Periksa apakah variabel diberi sesuatu atau nol, dalam hal ini ditetapkan jadi kami mencetaknya ke stdout

$ X=12345
$ if [ -z "$X" ]; then echo "X is null"; else echo $X; fi
12345

Periksa apakah variabel diberi sesuatu atau nol, dalam hal ini tidak disetel sehingga kami mencetak "adalah nol" alih-alih nilainya.

$ unset X
$ if [ -z "$X" ]; then echo "X is null"; else echo $X; fi
X is null

Ekspansi penjepit

Brace Expansion adalah fitur bash yang sangat kuat yang memungkinkan Anda menulis skrip dan perintah yang lebih ringkas. Ini memiliki banyak fitur dan opsi berbeda yang dijelaskan di bawah ini. Dalam kurung kurawal sintaks Anda ditafsirkan menjadi sintaks yang lebih verbose tergantung saat Anda memasukkan kurung kurawal. Mari kita lihat sejumlah contoh untuk Brace Expansion.

Setiap versi item dalam daftar dalam kurung kurawal dieksekusi. Jadi kita pergi dari satu perintah echo dan mencetak 3 versi kata di bawah ini dipisahkan oleh spasi.

$ echo {a,m,p}_warehouse
a_warehouse m_warehouse p_warehouse

Ekspresi dalam ekspansi menyebabkan eksekusi beberapa kali. Untuk membuktikannya, kami menggunakan perintah date dan sleep untuk memvalidasi bahwa perintah date dijalankan sekali untuk setiap iterasi pola dalam Brace Expansion.

$echo {a,m,p}_$(date; sleep 1)
a_Sun Mar 22 18:56:45 UTC 2020 m_Sun Mar 22 18:56:46 UTC
2020 p_Sun Mar 22 18:56:47 UTC 2020

Ekspansi menggunakan angka dengan.. akan menyebabkan angka urut diperluas dalam urutan numerik

$ echo {1..8}_warehouse
1_warehouse 2_warehouse 3_warehouse 4_warehouse 5_warehouse 6_warehouse 7_warehouse
8_warehouse

Ekspansi penjepit urutan terbalik dengan urutan angka

$ echo {8..1}_warehouse
8_warehouse 7_warehouse 6_warehouse 5_warehouse 4_warehouse 3_warehouse 2_warehouse
1_warehouse

Menggunakan nilai kenaikan opsional untuk menentukan peningkatan numerik ekspansi penjepit

$ echo {1..9..3}_warehouse
1_warehouse 4_warehouse 7_warehouse

Perluasan brace leksikografis akan beralih melalui huruf dalam alfabet dalam urutan lokal

$ echo {a..e}_warehouse
a_warehouse b_warehouse c_warehouse d_warehouse e_warehouse

Ekspansi penjepit leksikografis urutan terbalik

$ echo {e..a}_warehouse
e_warehouse d_warehouse c_warehouse b_warehouse a_warehouse

Ekspansi brace leksikografis dengan kenaikan yang ditentukan akan beralih melalui daftar karakter dari awal hingga titik akhir tetapi melewatkan karakter sesuai dengan nilai kenaikan

$ echo {a..z..5}_warehouse
a_warehouse f_warehouse k_warehouse p_warehouse u_warehouse z_warehouse

Ekspansi brace multiplikasi dengan 2 ekspansi brace dalam satu perintah

$ echo {a..e}{1..5}_warehouse
a1_warehouse a2_warehouse a3_warehouse a4_warehouse a5_warehouse b1_warehouse
 b2_warehouse b3_warehouse b4_warehouse b5_warehouse c1_warehouse c2_warehouse
 c3_warehouse c4_warehouse c5_warehouse d1_warehouse d2_warehouse d3_warehouse
 d4_warehouse d5_warehouse e1_warehouse e2_warehouse e3_warehouse e4_warehouse
 e5_warehouse

Perkuat ekspansi untuk menggunakan root yang sama dua kali dalam sebuah perintah. Ini membuat file tar foo.tgz dari direktori dengan nama foo. Ini adalah sintaks yang berguna di mana Anda menggunakannya di dalam loop lain dan ingin mengasumsikan bahwa dasar kata digunakan beberapa kali. Contoh ini menunjukkannya dengan tar, tetapi juga dapat digunakan dengan mv dan cp sesuai contoh ini.

$ mkdir foo
$ touch foo/foo{a..e}
$ tar czvf foo{.tgz,}
foo/
foo/foob
foo/fooc
foo/fooa
foo/food
foo/fooe

Ekspansi Parameter

Perluasan parameter juga merupakan sintaks ringkas yang bagus dengan banyak kemampuan seperti: izinkan skrip untuk menetapkan nilai default untuk variabel atau opsi yang tidak disetel, operasi substring string, pencarian dan penggantian substitusi, dan kasus useran lainnya. Contohnya di bawah ini.
 
Periksa null dan gunakan parameter jika bukan null atau nilai default. Dalam hal ini X tidak nol sehingga akan digunakan

$ X=1
$ echo ${X:-2}
1

Periksa null dan gunakan parameter jika bukan null atau nilai default. Dalam hal ini X adalah nol sehingga nilai default akan digunakan

$ unset X
$ echo ${X:-2}
2

Periksa apakah variabelnya NULL dan atur dan gema apakah itu NULL. X ditetapkan 2 dan dicetak $X. Ini dapat mengatur variabel dan menggunakannya dalam perintah dengan sintaks ${:=}.

$ unset X
$ if [ -z "$X" ]; then echo NULL; fi
NULL
$ echo ${X:=2}
2
$ if [ -z "$X" ]; then echo NULL; else echo $X; fi
2

Ekspansi substring akan menggantikan dari titik offset sejumlah karakter tertentu dalam string

$ X="Hello World"
$ echo ${X:0:7}
Hello W

Ubah offset ke karakter kedua dan cetak 7 karakter substring

$ X="Hello World"
$ echo ${X:1:7}
ello Wo

Substring dari awal string tetapi memotong 2 karakter terakhir

$ X="Hello World"
$ echo ${X:0:-2}
Hello Wor

Dapatkan panjang string dengan versi ekspansi parameter ini

$ X="Hello World"
$ echo ${#X}
11

Cari dan ganti dalam variabel. Dalam contoh ini ganti huruf kecil pertama o dengan huruf besar O

 $ echo ${X/o/O}
HellO World

Cari dan ganti dalam variabel tetapi dengan semua kecocokan diganti karena garis miring di pola pencarian.

$ X="Hello World"
$ echo ${X//o/O}
HellO WOrld

Pola dimulai dengan #, berarti kecocokan harus dimulai dari awal string untuk diganti

$ X="Hello World"
$ echo ${X/#H/J}
Jello World

Contoh di mana mencari kecocokan di awal string, tetapi gagal karena kecocokan nanti di string

$ X="Hello World"
$ echo ${X/#W/J}
Hello World

Pola yang dimulai dengan % hanya akan cocok di akhir string seperti dalam contoh ini.

$ X="Hello World"
$ echo ${X/%d/d Today}
Hello World Today

Contoh kecocokan akhir string yang gagal karena kecocokan berada di awal string.

$ X="Hello World"
$ echo ${X/%H/Today}
Hello World

Gunakan shopt dengan nocasematch untuk melakukan penggantian case-insensitive.

$ shopt -s nocasematch
$ X="Hello World"
$ echo ${X/hello/Welcome}
Welcome World

Matikan shopt dengan nocasematch untuk melakukan penggantian case sensitif.

$ shopt -u nocasematch
$ X="Hello World"
$ echo ${X/hello/Welcome}
Hello World

Cari variabel lingkungan yang cocok dengan pola.

$ MY_A=1
$ MY_B=2
$ MY_C=3
$ echo ${!MY*}
MY_A MY_B MY_C

Dapatkan daftar variabel yang cocok dan kemudian ulangi setiap variabel dan cetak nilainya

$ MY_A=1
$ MY_B=2
$ MY_C=3
$ variables=${!MY*}
$ for i in $variables; do echo $i; echo "${!i}"; done
MY_A
1
MY_B
2
MY_C
3

Buat string semua huruf besar

$ X="Hello World"
$ echo ${X^^}
HELLO WORLD

Make a string all lowercase
$ X="Hello World"
$ echo ${X,,}
hello world
 
Make first character of a string uppercase
$ X="george washington"
$ echo ${X^}
George washington
 
Make first character of a string lowercase
$ X=BOB
$ echo ${X,}
bOB

Parameter Posisi

Parameter Posisi biasanya dianggap sebagai parameter command line, cara menggunakannya ditunjukkan dengan contoh di bawah ini.

Parameter $0 adalah nama skrip yang sedang berjalan dan kemudian $1, $2, $3 dll adalah parameter command line yang diteruskan ke skrip.

$ cat script.sh
echo $0
echo $1
echo $2
echo $3
$ bash./script.sh apple banana carrot
./script.sh
apple
banana
carrot

Parameter $* adalah variabel tunggal dengan semua argumen command line yang digabungkan.

$ cat script.sh
echo $1
echo $2
echo $*
$ bash./script.sh apple banana
apple
banana
apple banana

Parameter $# adalah angka dengan jumlah parameter posisi yang diteruskan ke skrip dalam hal ini di bawah ini ada 2 argumen yang diteruskan.

$ cat script.sh
echo $1
echo $2
echo $*
echo $#
$ bash./script.sh apple banana
apple
banana
apple banana
2

Ekspansi Tilde

Perluasan Tilde biasanya terlihat dengan nama user dan direktori home, contohnya ditunjukkan di bawah ini.

Tilde Expansion untuk mendapatkan direktori HOME dari user saat ini, hanya menggunakan tilde tanpa nama user.

$ echo $USER
root
$ cd ~/
$ pwd
/root

Lihat direktori home user tertentu, bukan user saat ini dengan Tilde dan nama user

$ cd ~linuxhint
$ pwd
/home/linuxhint

Substitusi Aritmatika

Substitusi Aritmatika memungkinkan bash untuk melakukan operasi matematika di shell atau dalam skrip. Contoh useran umum ditunjukkan di bawah ini.

Substitusi Aritmatika Sederhana dengan $ dan tanda kurung ganda

$ echo $((2 + 3))
5

Operator kenaikan pos akan memperbarui nilai satu per satu setelah perintah saat ini, perhatikan ada pengurangan pos yang setara yang tidak ditampilkan di sini.

$ X=2
$ echo $((X++))
2
$ echo $X
3

Operator pra kenaikan akan memperbarui nilai satu per satu tepat sebelum perintah saat ini, perhatikan bahwa ada operator penurunan sebelumnya yang setara yang tidak ditampilkan di sini.

$ X=2
$ echo $((++X))
3
$ echo $X
3

Operator eksponen dapat menaikkan angka ke pangkat secara eksponensial

$ echo $((5**2))
25

Pergeseran bitwise kiri; dalam hal ini menggeser bit angka desimal 8 ke kiri yang pada dasarnya mengalikannya dengan 2

$ echo $((8<<1))
16

Pergeseran bitwise kanan; dalam hal ini menggeser bit angka desimal 8 ke kanan yang pada dasarnya membagi angka dengan 2

$ echo $((8>>1))
4

Bitwise AND Operator akan membandingkan angka-angka sedikit demi sedikit dan dan hasilnya adalah bit-bit yang sudah diset.

$ echo $((4 & 5))
4

Bitwise OR Operator akan membandingkan angka-angka sedikit demi sedikit dan hasilnya akan menjadi bit-bit di mana salah satu input memiliki bit yang ditetapkan.

$ echo $((4 | 9))
13

Operator persamaan aritmatika akan menguji kebenaran dan mengembalikan 1 atau 0

$ echo $((4 == 4))
1

Operator ketidaksetaraan aritmatika akan menguji ketidaksetaraan dan mengembalikan 1 atau 0

$ echo $((4 != 4))
0

Operator Bersyarat akan menguji argumen pertama jika benar, ganti dengan argumen kedua dan jika salah ganti dengan yang ketiga. Dalam hal ini 5 sama dengan 4+1 sehingga kondisi pertama benar dan 9 dikembalikan. 5 tidak sama dengan 4+2 sehingga pada gema kedua 7 dikembalikan.

$ echo $(( 5==4+1 ? 9 : 7 ))
9
$ echo $(( 5==4+2 ? 9 : 7 ))
7

Anda dapat menggunakan bilangan heksadesimal dalam ekspansi aritmatika, dalam hal ini 0xa setara dengan 10 dan 10+7 = 17.

$ echo $(( 0xa + 7 ))
17

Pemisahan Kata

Menggunakan variabel lingkungan IFS untuk mendaftarkan pembatas, dan menggunakan perintah read dan readarray kita dapat mengurai string ke dalam array token dan kemudian menghitung token dan mengoperasikannya. Contohnya ditunjukkan di bawah ini.
 
Gunakan parameter IFS sebagai pembatas, baca token ke dalam array yang dibagi oleh IFS yang disetel ke karakter spasi, lalu cetak token satu per satu

$ text="Hello World"
$ IFS=' '
$ read -a tokens <<< "$text"
$ echo "There are ${#tokens[*]} words in the text."

Ada 2 kata dalam teks tersebut.

$ for i in "${tokens[@]}"; do echo $i; done
Hello
World

Readarray user tanpa IFS dan tentukan pembatas dalam perintah readarray. Perhatikan ini hanyalah contoh di mana kami membagi jalur direktori berdasarkan pembatas garis miring. Dalam hal ini kode telah menyertakan string kosong sebelum garis miring pertama yang perlu disesuaikan dalam useran nyata, tetapi kami hanya menunjukkan cara memanggil readarray untuk membagi string menjadi token dalam array dengan pembatas.

$ path="/home/linuxhint/usr/local/bin"
$ readarray -d / -t tokens <<< "$path"
echo "There are ${#tokens[*]} words in the text."

Ada 6 kata dalam teks.

$ for i in "${tokens[@]}"; do echo $i; done
 
home
linuxhint
usr
local
bin

Perluasan Nama File

Saat ingin merujuk ke daftar file atau direktori di sistem file, perintah bash atau skrip bash dapat menggunakan Ekspansi Nama File untuk menghasilkan daftar file dan direktori dari perintah sederhana. Contohnya ditunjukkan di bawah ini.

Karakter * diperluas ke wildcard dan mengambil semua file yang cocok dengan sisa string wild card. Di sini kami mengambil semua file yang diakhiri dengan.txt dan meneruskannya ke perintah du untuk memeriksa ukuran disk.

$ touch a.txt b.txt c.txt
$ echo "Hello World" > content.txt
$ du *.txt
0          a.txt
0          b.txt
0          c.txt
4          content.txt

? karakter hanya akan cocok dengan satu karakter bukan jumlah karakter yang tak terbatas, dan oleh karena itu dalam contoh ini hanya akan mengambil nama file dengan satu karakter diikuti dengan.txt.

$ touch a.txt b.txt c.txt
$ echo "Hello World" > content.txt
$ du ?.txt
0          a.txt
0          b.txt
0          c.txt

Karakter dalam tanda kurung diperluas agar sesuai dengan karakter mana pun. Dalam contoh ini a.txt dan c.txt diambil oleh ekspansi

$ touch a.txt b.txt c.txt
$ echo "Hello World" > content.txt
$ du [ac].txt
0          a.txt
0          c.txt

Karakter dalam tanda kurung dapat berupa rentang karakter dan kita lihat di sini semua file dari rentang a hingga c diikuti oleh akhiran.txt diambil

$ touch a.txt b.txt c.txt
$ echo "Hello World" > content.txt
$ du [a-c].txt
0          a.txt
0          b.txt
0          c.txt

Kesimpulan

Kami telah membahas banyak jenis ekspansi shell dalam artikel ini, dan saya harap contoh sederhana dapat berfungsi sebagai buku masak untuk apa yang mungkin dilakukan di bash untuk membuat Anda lebih produktif dengan ekspansi shell. Sebagai referensi lebih lanjut, saya sarankan membaca Manual Bash lengkap, dan juga banyak artikel bagus di situs web NixCraft tentang skrip bash termasuk Ekspansi Shell. Kami memiliki artikel lain yang mungkin menarik bagi Anda di LinuxHint termasuk: 30 Contoh Skrip Bash, String Huruf Kecil Bash, Pencocokan Pola Bash, dan Contoh String Split Bash. Kami juga memiliki kursus 3 jam gratis yang populer tentang Pemrograman Bash yang dapat Anda temukan di YouTube.

Related Posts