Perulangan dan Seleksi
Sebagian besar bahasa pemrograman mempunyai konsep perulangan atau
loop. Jika kita
perlu mengulangi suatu tugas sebanyak 20 kali, kita tidak harus
menuliskan kode yang
sama sebanyak 20 kali. Shell Bash menyediakan perulangan for dan while. Shell Linux
memang menyediakan lebih sedikit fitur dibandingkan bahasa dunia
C/C++.
Perulangan For
Perulangan for digunakan untuk melakukan pekerjaan berulang sebanyak daftar yang
disediakan:
#!/bin/sh
#
Nama file skrip: for1.sh
for
i in 1 2 3 4 5
do
echo
"Looping ... number $i"
done
Coba eksekusi dan perhatikan hasil yang diperoleh. Program di atas
meminta shell
mengeksekusi perintah-perintah di dalam blok do...done sebanyak jumlah elemen di
dalam daftar setelah in, yaitu 5 (1, 2, 3, 4, 5).
Penulisan elemen dari daftar juga dapat berbentuk seperti pada
contoh di bawah ini:
#!/bin/sh
#
Nama file skrip: for2.sh
for
i in hello 1 * 2 goodbye
do
echo
"Looping ... i is set to $i"
done
Pastikan bahwa anda memahami apa yang terjadi di sini. Coba
hilangkan tanda * dan ulangi lagi dengan kembali menyertakan *. Anda tentu tahu
apa yang dihasilkan saat eksekusi. Coba
jalankan skrip di atas dari dalam direktori lain. Coba apit * dengan tanda
petik
ganda, menjadi “*”. Bagaimana jika * didahului backslash (\*) ? Skrip pertama (for1.sh) memberikan hasil eksekusi
berikut:
Looping
..... number 1
Looping
..... number 2
Looping
..... number 3
Looping
..... number 4
Looping
..... number 5
Sedangkan skrip kedua (for2.sh) menunjukka hasil ekskusi
berikut:
Looping
... i is set to hello
Looping
... i is set to 1
Looping
... i is set to (nama dari file pertama dalam direktori aktif)
... dan seterusnya ...
Looping
... i is set to (nama dari file terakhir dalam direktori aktif)
Looping
... i is set to 2
Looping
... i is set to goodbye
Seperti terlihat, for melakukan perulangan sebanyak input yang diberikan kepadanya, dari
input pertama sampai terakhir.
Perulangan
While
Perulangan
while dapat digunakan untuk melakukan pekerjaan berulang yang jumlah
perulangannya
tidak pasti tetapi bergantung pada suatu kondisi yang harus dipenuhi.
Perhatikan
skrip berikut:
#!/bin/sh
# Nama file
skrip: while.sh
INPUT_STRING=hello
while [
"$INPUT_STRING" != "bye" ]
do
echo
"Ketikkan sesuatu (bye untuk keluar)"
read
INPUT_STRING
echo "Anda
mengetikkan: $INPUT_STRING"
done
Apa
yang terjadi di sini? Pernyataan echo dan read akan
dijalankan secara terus menerus
sampai
anda mengetikan "bye". Mengapa variabel INPUT_STRING diberi nilai awal
“hello”?
Simbol
titik-dua (:) selalu bernilai true; ini dapat digunakan pada waktu tertentu.
Skrip di
bawah
ini menunjukkan cara keluar program yang lebih elegan dari sebelunnya.
#!/bin/sh
# Nama file
skrip: while2.sh
while :
do
echo
"Ketikkan sesuatu (^C untuk keluar)"
read
INPUT_STRING
echo "Anda
mengetikkan: $INPUT_STRING"
done
Shell menyediakan while berbentuk while read f. Contoh di bawah ini menggunakan pernyataan case yang akan dihabas pada bagian lain
panduan ini. Skrip ini membaca dari file myfile, dan
untuk setiap baris,
memberitahukan pengguna bahasa
apa yang digunakan. Setiap baris
harus diakhiri dengan LF (baris baru) - jika cat myfile tidak berakhir dengan suatu baris blank (kosong) maka baris
terakhir tersebut tidak akan diproses.
#!/bin/sh
#
Nama file skrip: while3a.sh
while
read f
do
case
$f in
hello)
howdy)
gday)
bonjour)
"guten
tag")
"apa
kabar")
*)
;;
esac
done
< myfile
echo
English ;;
echo
American ;;
echo
Australian ;;
echo
French ;;
echo
German ;;
echo
Indonesian ;;
echo
Unknown Language: $f
Pada banyak sistem Linux, ini dapat pula dilakukan dengan:
#!/bin/sh
# Nama file skrip: while3b.sh
while f=`line`
do
.. proses f ..
done < myfile
Karena while
read f bekerja hanya dengan Linux dan tidak
bergantung pada program eksternal line maka
bentuk pada while3a.sh
lebih disukai. Mengapa
metode ini menggunakan backtick
(`)?
Banyak programmer lebih menyukai $i (bukan $f) sebagai default untuk perulangan. Berikut ini
adalah contoh eksekusi dari skrip while3a.sh:
$
i=THIS_IS_A_BUG
$
export i
$
./while3a.sh something
Unknown
Language: THIS_IS_A_BUG
Hindari kesalahan ketik. Lebih baik menggunakan ${x}, bukan hanya $x. Jika x="A" dan anda ingin mengatakan "A1"
maka anda perlu echo ${x}1,
sedangkan echo $x1 akan mencoba mengakses
variabel x1 yang sebenarnya tidak
ada.
Ada hal yang sangat menarik pada shell Bash. Pembuatan banyak
direktori dengan nama hampir sama dapat
dilakukan dengan mudah. Misalnya membuat 8 direktori berawalan “rc” kemudian
dilanjutkan suatu angka atau huruf dan diakhir dengan “.d”, dapat ditulis:
mkdir
rc{0,1,2,3,4,5,6,S}.d
lebih sederhana dari pada anda menulis:
for
runlevel in 0 1 2 3 4 5 6 S
do
mkdir
rc${runlevel}.d
done
Perhatikan cara rekursif penggunaan perintah ls berikut. Kita
dapat menampilkan daftar file dari banyak direktori sekaligus.
$
cd /
$
ls -ld {,usr,usr/local}/{bin,sbin,lib}
drwxr-xr-x
2 root root 4096 Oct 26 01:00 /bin
drwxr-xr-x
6 root root 4096 Jan 16 17:09 /lib
drwxr-xr-x
2 root root 4096 Oct 27 00:02 /sbin
drwxr-xr-x
2 root root 40960 Jan 16 19:35 usr/bin
drwxr-xr-x
83 root root 49152 Jan 16 17:23 usr/lib
drwxr-xr-x
2 root root 4096 Jan 16 22:22 usr/local/bin
drwxr-xr-x
3 root root 4096 Jan 16 19:17 usr/local/lib
drwxr-xr-x
2 root root 4096 Dec 28 00:44 usr/local/sbin
drwxr-xr-x
2 root root 8192 Dec 27 02:10 usr/sbin
Perulangan while sering
digunakan bersama dengan
seleksi kondisi memanfaatkan perintah test dan case.
III.2 Seleksi Kondisi
Test
Test digunakan secara virtual oleh setiap skrip shell yang ditulis. Test memang tidak
sering dipanggil secara langsung. Test sering dipanggil sebagai [. [ adalah
link simbolik ke perintah
test, membuat program shell lebih nyaman dibaca.
Coba tulis perintah di bawah ini dan perhatikan luarannya:
$
type [
[
is a shell builtin
$
which [
/usr/bin/[
$
ls -l /usr/bin/[
lrwxrwxrwx
1 root root 4 Mar 27 2000 /usr/bin/[ -> test
Ini berarti bahwa '[' sebenarnya adalah sebuah program yang sudah
built-in seperti ls. Karena
termasuk perintah maka saat penggunaan ‘[‘ harus diberi jarak (spasi) saat
digunakan bersama string atau perintah lain.
Seleksi kondisi seperti ini:
if
[$foo == "bar" ] tidak akan bekerja.
Baris tersebut diterjemahkan sebagai if test$foo
== "bar" ], dimana
terdapat ']' tanpa '[' permulaan. Letakkan spasi di awal dan akhir semua
operator.
Jika anda menjumpai
kata ‘SPACE’ di dalam
panduan ini, berarti
anda diminta menggatinya dengan
spasi. Jika tidak ada spasi maka skrip shell tidak bekerja:
if
SPACE [ SPACE "$foo" SPACE == SPACE "bar" SPACE ]
Test merupakan tool perbandingan yang sederhana tetapi powerful.
Gunakan perintah man test untuk mengetahui manual lengkap dari perintah test.
Test sering dipanggil secara tak langsung melalui pernyataan if dan while. Sintaks untuk if...then...else... adalah
if
[ ... ]
then
#
if-code
else
#
else-code
fi
Pernyataan fi merupakan kebalikan dari if. Bentuk seperti ini juga digunakan pada case dan esac. Anda juga
perlu waspadai sintaks - perintah "if [
... ]" dan "then"
harus pada baris-baris berbeda. Sebagai alternatif, titik-koma ";" dapat digunakan untuk memisahkannya:
if
[ ... ]; then
#
lakukan sesuatu
fi
Anda juga dapat menggunakan elif, seperti ini:
if [ something ]; then
echo "Something"
elif [ something_else ]; then
echo "Something else"
else
echo "None of the
above"
fi
Skrip di atas akan meng-echo "Something" jika test
terhadap [
something ] berhasil, jika tidak maka dilakukan test
terhadap [
something_else ] dan memroses echo "Something else" jika berhasil. Jika
semuanya gagal, maka akan menjalankan echo "None of the above". Coba praktekkan potongan kode berikut.
Sebelum menjalankannya set variabel X untuk beberapa nilai (coba -1, 0, 1,
hello, bye, dan lain-lain). Anda dapat melakukan ini sebagai
berikut:
$
X=5
$
export X
$
./test.sh
...
output of test.sh ... $
X=hello
$
./test.sh
...
output of test.sh ... $
X=test.sh
$
./test.sh
...
output of test.sh ...
Kemudian coba lagi, dengan $X sebagai nama dari file yang ada,
misalnya /etc/hosts.
#!/bin/sh
#
Nama file skrip: test.sh
if
[ "$X" -lt "0" ]
then
echo
"X is less than zero"
fi
if
[ "$X" -gt "0" ]; then
echo
"X is more than zero"
fi
[
"$X" -le "0" ] && \
echo
"X is less than or equal to
zero" [
"$X"
-ge "0" ] && \
echo
"X is more than or equal to zero" [
"$X"
= "0" ] && \
echo
"X is the string or number \"0\"" [
"$X"
= "hello" ] && \
echo
"X matches the string \"hello\"" [
"$X"
!= "hello" ] && \
echo
"X is not the string \"hello\"" [
-n
"$X" ] && \
echo
"X is of nonzero length"
[
-f "$X" ] && \
echo
"X is the path of a real file" || \
echo
"No such file: $X"
[
-x "$X" ] && \
echo
"X is the path of an executable file" [
"$X"
-nt "/etc/passwd" ] && \
echo
"X is a file which is newer than /etc/passwd"
Perlu diketahui bahwa kita dapat menggunakan titik-koma (;) untuk menggabungkan dua baris (menjadi satu
baris). Ini sering dilakukan untuk menghemat ruang dalam pernyataan if yang
sederhana. Karakter backslash memberitahukan shell bahwa ini bukanlah
akhir baris, tetapi dua atau lebih baris agar diperlakukankan sebagai satu
baris. Ini berguna untuk memudahkan pembacaan kode. Biasanya baris berikutnya diinden (agak masuk
ke dalam).
Perintah test dapat
mengerjakan banyak pengujian terhadap bilangan, string dan nama file. Perlu diketahui bahwa parameter -a, -e (berarti "file
exists"), -S (file is a Socket), -nt (file is newer than), -ot (file is older than), -ef (paths refer to the same file) dan -O (file is owned my user) tidak tersedia pada shell Bash lama
(seperti /bin/sh pada Solaris, AIX, HPUX, dan lain-lain).
Ada cara yang lebih mudah dalam menuliskan pernyataan if: Perintah && dan ||
menyebabkan kode tertentu dijalankan jika test bernilai True.
#!/bin/bash
[
$X -ne 0 ] && echo "X isn't zero" || echo "X is
zero"
[
-f $X ] && echo "X is a file" || echo "X is not a
file" [
-n
$X ] && echo "X is of non-zero length" || \
echo "X is of zero length"
Perlu dicatat bahwa ketika anda mengubah nilai X ke suatu nilai
non-numerik, beberapa perbandingan
awal memberikan pesan berikut:
test.sh:
[: integer expression expected before -lt
test.sh:
[: integer expression expected before -gt
test.sh:
[: integer expression expected before -le
test.sh:
[: integer expression expected before -ge
Ini karena -lt, -gt, -le, -ge adalah perbandingan dirancang hanya
untuk integer dan tidak berjalan terhadap string. Perbandingan string seperti != akan memperlakukan "5" sebagai suatu string, tetapi
tidak dapat memperlakukan "Hello" sebagai suatu integer, sehingga
perbandingan integer bermasalah. Jika anda ingin skrip shell berjalan lebih
baik, maka periksa terlebih dahulu isi variabel sebelum dilakukan test -
mungkin menjadi seperti ini:
echo
-en "Please guess the magic number: "
read
X
echo
$X | grep "[^0-9]" > /dev/null 2>&1
if
[ "$?" -eq "0" ]; then
#
If the grep found something other than 0-9 #
then
it's not an integer.
echo
"Sorry, wanted a number"
else
#
The grep found only 0-9, so it's an integer. #
We
can safely do a test on it.
if
[ "$X" == "7" ]; then
echo
"You entered the magic number!"
fi
fi
Pada cara ini anda dapat meng-echo pesan yang lebih bermakna kepada
pengguna dan keluar (exit). Variabel $? akan dijelaskan pada bagian lain panduan
ini dan perintah grep perlu
dipelajari lebih lanjut. Perintah grep [0-9] mencari baris teks yang mengandung digit
(0-9). Tanda caret (^) dalam grep [^0-9] hanya akan mencari baris yang hanya tidak mengandung bilangan. Apa yang
dihasilkan perintah grep -v [0-9]? Perintah test dapat digunakan dalam perulangan while. Contohnya
adalah:
#!/bin/sh
#
Nama file skrip: test2.sh
X=0
while
[ -n "$X" ]
do
echo
"Masukkan teks (ENTER untuk keluar)"
read
X
echo
"Anda menulis: $X"
done
Kode ini akan terus meminta input sampai anda menekan ENTER (X
panjangnya nol). Bagaimana jika while [ -n "$X" ] diganti dengan while [ -n $X ],
dengan menghilangkan dua tanda petik gandanya? Perhatikan eksekusi di bawah
ini:
$
./test2.sh
Masukkan
teks (ENTER untuk keluar)
fred
Anda
menulis: fred
Masukkan
teks (ENTER untuk keluar)
wilma
Anda
menulis: wilma
Masukkan
teks (ENTER untuk keluar)
Anda
menulis:
$
Kode di atas dapat dibuat lebih rapi dengan menyertakan test di
dalam loop:
#!/bin/sh
#
Nama file skrip: test3.sh
X=0
while
[ -n "$X" ]
do
echo
"Enter Masukkan teks (ENTER untuk keluar)"
read
X
if
[ -n "$X" ]; then
echo
" Anda menulis: $X"
fi
done
Anda telah menggunakan dua sintaks berbeda untuk pernyataan if di atas, yaitu:
if
[ "$X" -lt "0" ]
then
echo
"X lebih kecil daripada nol"
fi
.......... dan ..........
if
[ ! -n "$X" ]; then
echo "You said: $X" fi
Case
Pernyataan case menghemat pernyataan if .. then .. else banyak baris. Sintaksnya
sangat sederhana:
#!/bin/sh
#
Nama file skrip: talk.sh
echo
"Please talk to me ..."
while
:
do
read
INPUT_STRING
case
$INPUT_STRING in
hello)
esac
done
echo
echo
"Hello yourself!"
;;
bye)
echo
"See you again!"
break
;;
*)
echo
"Sorry, I don't understand"
;;
echo
"That's all folks!"
Coba jalankan kode di atas dan perhatikan bagaimana
kerjanya...
$
./talk.sh
Please
talk to me ...
hello
Hello
yourself!
What
do you think of politics?
Sorry,
I don't understand
bye
See
you again!
That's
all folks!
Baris case sendiri selalu berformat sama. Dimulai dengan memeriksa nilai
suatu variable kondisi, pada contoh di atas adalah variabel INPUT_STRING.
Pilihan-pilihan kemudian didaftarkan dan diikuti oleh suatu kurung
tutup seperti hello)
dan bye). Ini berarti bahwa jika INPUT_STRING cocok dengan hello maka bagian kode itu
dieksekusi, sampai dengan dua titik-koma. Jika INPUT_STRING cocok dengan bye
maka pesan
“goodbye” dicetak dan keluar dari perulangan. Jika anda ingin keluar dari skrip maka dapat menggunakan perintah exit, bukan break. Pilihan ketiga, di sini *), merupakan kondisi catch-all default; tidak harus tetapi
sering berguna untuk tujuan debugging bahkan jika kita mengetahui nilai apa yang akan
dimiliki variabel dalam test. Pernyataan case lengkap diakhiri dengan esac dan loop while diakhiri dengan done.
Contoh skrip untuk memeriksa kesalahan username dari sistem Linux! Penguna memberikan inputan dari keyboard (gunakan perintah read)
Contoh skrip untuk memeriksa kesalahan username dari sistem Linux! Penguna memberikan inputan dari keyboard (gunakan perintah read)



Tidak ada komentar:
Posting Komentar