Kamis, 13 Desember 2012

Modul 2

VARIABEL dan KARAKTER ESCAPE


Perlu dicatat bahwa harus tidak ada spasi (ruang) sebelum dan sesudah tanda sama dengan ("="): VAR=value benar sedangkan VAR =  value tidak bekerja. Pada kasus pertama, shell melihat  simbol "=" dan memperlakukan perintah sebagai pemberian atau pelewatan variabel. Pada kasus kedua, shell menganggap bahwa VAR harus berupa nama perintah dan mencoba mengeksekusinya. 
Coba tulis kode berikut ke dalam file skrip var1.sh:
#!/bin/sh
# Nama file skrip: var1.sh
MY_MESSAGE="Halo dunia" echo
$MY_MESSAGE


Ini melewatkan string "Halo dunia" ke variabel MY_MESSAGE kemudian meng-echo-kan nilai dari variabel tersebut.
Kita harus mengapit string Halo  dunia dengan tanda petik. Tidak ada masalah dengan perintah echo  Halo  dunia. Perintah echo menerima semua parameter yang diberikan. Variabel hanya dapat memegang satu nilai, sehingga suatu string yang mengandung spasi harus diapit tanda petik agar shell mengetahui dan menganggap semuanya sebagai satu. Jika tidak, shell akan mencoba mengeksekusi perintah dunia setelah MY_MESSAGE=Halo
Shell  tidak  mengenal  tipe  variabel;  variabel  boleh  menyimpan  string,  integer  dan bilangan ril - apa pun yang diinginkan. Programmer yang telah terbiasa dengan PHP dan Perl menyukai ini. Jika anda menggunakan C, Pascal atau Ada, ini terasa aneh. Semua nilai   disimpan   sebagai   string, tetapi   rutin   yang   mengharapkan   numerik   dapat memperlakukannya sebagai nilai numerik.
Jika anda melewatkan string ke suatu variabel  kemudian mencoba untuk menambahkan 1 ke variabel tersebut, anda dilarang melakukannya:
$ x="hello"
$ y=`expr $x + 1`
expr: non-numeric argument 
Karena program eksternal bernama expr hanya mengharapkan numerik. Berikut ini adalah contoh pembuatan variabel yang benar: 
MY_MESSAGE="Halo dunia"
MY_SHORT_MESSAGE=hi 
MY_NUMBER=1; MY_PI=3.142
MY_OTHER_PI="3.142"; MY_MIXED=123abc
Karakter khusus harus dengan tepat di-escape untuk menghindari salah interpretasi oleh shell. 
Kita dapat secara interaktif meminta pengguna memasukkan nilai untuk suatu variabel menggunakan perintah read. Kode berikut menanyakan pengguna nilai untuk variabel MY_NAME,   menggabungkan   nilai   variabel   tersebut   dengan   string   lain   dan mencetaknya. 
#!/bin/sh
# Nama file skrip: var2.sh
echo Who are U? 
read MY_NAME
echo "Hello $MY_NAME - hope you're well."



Apa yang terjadi jika baris terakhir tidak dilingkupi tanda pentik ganda? Karakter petik tunggal di dalam "you're" tidak cocok sehingga dapat memunculkan error. Hati-hati! 
Contoh di atas menggunakan perintah bawaan (built-in) shell read yang membaca baris dari  input standard (biasanya keyboard) ke dalam variabel.  Jika anda memasukkan nama lengkap (lebih dari satu kata) dan tidak menggunakan petik ganda di awal dan akhir perintah echo, maka luaran masih tetap benar. Bagaimana ini terjadi? Variabel MY_NAME telah lingkupi petik ganda.  Perintah read secara otomatis menempatkan tanda petik sekeliling inputnya, sehingga spasi tersebut diperlakukan dengan tepat.

2.1  Lingkup variabel
Variabel dalam shell Bash tidak harus dideklarasikan, sebagaimana dilakukan dalam bahasa lain seperti C. Tetapi jika anda membaca suatu variabel yang tidak dideklarasi, hasilnya  adalah  string  kosong.  Anda  tidak  mendapatkan  pesan  error.  Ini  dapat menyebabkan beberapa bug kecil - jika anda mempunyai variabel MY_OBFUSCATED_VARIABLE=Hello dan kemudian memanggil echo $MY_OSFUCATED_VARIABLE. Anda tidak akan mendapatkan apapun (karena OBFUSCATED kedua salah ejaan).
Ada perintah export yang mempunyai suatu efek penting terhadap lingkup variabel. Anda harus memahami bagaimana perintah ini digunakan.  Buat sebuah skrip shell kecil bernama myvar2.sh:  
#!/bin/sh
# Nama file skrip: myvar2.sh 
echo "MYVAR is: $MYVAR"
MYVAR="hako sen there"
echo "MYVAR is: $MYVAR" 



Sekarang jalankan skrip tersebut:
$ ./myvar2.sh
MYVAR is:
MYVAR is: hi there 



MYVAR belum diset ke suatu nilai, sehingga blank (kosong). Bagimana jika  kita berikan suatu nilai untuk variabel tersebut melalui shell  interaktif? Apa  hasilnya? Lakukan apa yang diilustrasikan di bawah ini: 
$ MYVAR=hello
$ ./myvar2.sh 
MYVAR is:
MYVAR is: hi there 



Ternyata variabel MYVAR masih belum menyimpan suatu nilai. Mengapa? Saat anda memanggil  myvar2.sh   dari   shell   interaktif,   suatu   shell   baru   dilahirkan   untuk menjalankan skrip. Ini  terjadi karena adanya baris #!/bin/sh pada awal skrip. Artinya, variabel MYVAR pada shell interaktif berbeda dengan MYVAR di dalam skrip yang dijalankan pada shell lain. 
Bagaimana agar nilai variabel pada shell interaktif dapat masuk ke dalam skrip? Perintah export jawabannya. Sekarang tulis baris-baris berikut: 
$ export MYVAR
$ ./myvar2.sh 
MYVAR is: hello
MYVAR is: hi there




Perhatikan baris ke-3 dari skrip yang bertugas untuk mengubah nilai dari MYVAR. Tetapi tidak ada cara yang dapat digunakan untuk mengirim balik nilai variabel ke shell interaktif. Coba baca nilai dari MYVAR setelah eksekusi skrip shell: 
$ echo $MYVAR
Hello
Begitu skrip shell keluar, variabel lingkungannya dihancurkan.  Tetapi MYVAR menjaga nilainya hello di dalam shell interaktif. Adakah caranya agar nilai variabel dari dalam skrip shell juga dapat diekspor ke shell interaktif? Gunakan operator titik "." saat memanggil   skrip   shell.   Jika   sebelumnya   anda   memanggil   skrip   dengan “./nama_file.sh” maka sekarang anda harus menulisnya “../nama_file.sh”.
Perhatikan contoh berikut:   
$ MYVAR=hello
$ echo $MYVAR 
hello
$ . ./myvar2.sh
MYVAR is: hello
MYVAR is: hi there
$ echo $MYVAR 
hi there
Inilah   bagaimana   file  .profile   atau  .bash_profile   bekerja,   sebagai   contoh. Dalam kasus ini, kita tidak perlu meng-export  MYVAR. Pastikan bukan echo  MYVAR tetapi echo $MYVAR.
Satu hal lain yang sering memunculkan kesalahan dalam pemanfaatan variabel adalah seperti pada contoh berikut: 
#!/bin/sh
# Nama file skrip: user.sh
echo " Siapa nama anda?"
read USER_NAME 
echo " Halooo $USER_NAME" 
echo " Buat file bernama $USER_NAME_file"
touch $USER_NAME_file
echo "Test 1 2 3" >> "${USER_NAME}_file"
cat "${USER_NAME}_file"
Apa yang dihasilkan skrip user.sh di atas? Misalnya anda memasukkan "steve" sebagai USER_NAME,    apakah    skrip    akan    membuatkan    file    bernama   steve_file? TIDAK. Ini akan memunculkan  error kecuali sebelumnya telah ada ada sebuah variabel bernama  USER_NAME_file.  Shell  tidak  mengetahui  dimana  ujung  dari  variabel. Bagaimana menyelesaikan ini? Jawabannya adalah kita meletakkan variabel tersebut di dalam kurung kurawal. 
Sekarang ubah skrip di user.sh menjadi sebagai berikut: 
#!/bin/sh
echo "Siapa nama anda?"
read USER_NAME 
echo "Halooo $USER_NAME"
echo "Buat file bernama ${USER_NAME}_file"
touch ${USER_NAME}_file 
echo "Test 1 2 3" >> "${USER_NAME}_file"
cat "${USER_NAME}_file" 


Shell  telah  mengetahui    bahwa  kita  mengacu  ke  variabel  USER_NAME  dan  ingin menambahkan  akhiran _file   kepada  nilai  dari  variabel.  Berhati-hatilah.  Banyak pemrogram shell pemula melupakan hal sederhana ini. 
Perlu juga dicatat bahwa  petik ganda yang melingkupi "${USER_NAME}_file" - jika pengguna  memasukkan  "Steve  Parker" (perhatikan  spasi)  maka  tanpa  tanda  petik, argumen yang dilewatkan ke perintah touch menjadi Steve dan Parker_file - yaitu, dapat dikatakan berupa touch  Steve  Parker_file yang akan men-touch dua file, bukan satu. Tanda petik menghindari masalah ini.

2.2  Wildcard
Wildcard atau karakter asterisk (*) bukanlah hal baru jika anda telah biasa menggunakan console Linux. Bagian ini memaparkan bagaimana asterisk digunakan dalam skrip shell.
Bagaimana anda menyalin semua file dari direktori /tmp/a ke dalam direktori /tmp/b. Bagaimana jika yang disalin semua file berekstensi .txt? Semua file terakhiran .html? Anda dapat menjawabnya dengan: 
$ cp /tmp/a/* /tmp/b/
$ cp /tmp/a/*.txt /tmp/b/
$ cp /tmp/a/*.html /tmp/b/ 
Sekarang   bagaimana   anda   mendapatkan   daftar   file   di   dalam  /tmp/a/   tanpa menggunakan  perintah  ls  /tmp/a/?  Bagaimana  dengan  echo  /tmp/a/*?  Apa perbedaan utama luaran dari echo dan ls? Bergunakah ini? Bagaimana anda mengganti nama (rename) semua file terekstensi .txt menjadi .bak? 
Perintah: 
$ mv *.txt *.bak 
Tidak akan memberikan hasil yang diharapkan. Coba gunakan echo bukan mv.

2.3  Karakter Escape
Ada sejumlah karakter tertentu memiliki arti khusus bagi shell; Misalnya karakter petik ganda (") yang menyebabkan shell memperhitungkan spasi dan TAB dalam pemrosesan teks, sebagai contoh: 
$ echo Halo    Dunia
Halo Dunia
$ echo "Halo   Dunia"
Halo Dunia
Bagaimana menampilkan Halo   "Dunia" ?
$ echo "Halo   \"Dunia\""
Karakter " pertama dan terakhir membungkus semuanya ke dalam satu parameter yang dilewatkan ke perintah echo sehingga spasi yang ada antara dua kata tetap dijaga. Tetapi kode: 
$ echo "Halo   " Dunia "" 
Akan diinterpretasikan sebagai tiga parameter: "Halo"   Dunia   "" 
Sehingga luarannya berupa: 
Hello World
Perhatikan, tanpa petik ganda yang mengapit kata Dunia dinyatakan hilang. Ini karenatanda petik pertama dan kedua mematikan teks Hello dan diikuti oleh spasi, sebagai argumen pertama; argumen kedua adalah teks Dunia tanpa tanda petik dan argumen ketiga merupakan string kosong "". 
Anda harus berhati-hati, perhatikan kode berikut: 
$ echo "Hello   "World""
Sebenarnya memanggil perintah echo dengan hanya satu parameter (tak ada spasi antaraparamater yang diapit tanda petik) dan anda dapat menguji ini dengan menggantperintah echo dengan misalnya perintah ls
Sebagian besar karakter (*', dll) tidak diterjemahkan jika diletakkan di dalam petik ganda (").  Semua  karakter  diterima  begitu  saja  dan  dilewatkan  ke  perintah  yang dipanggil. Contoh menggunakan asterisk (*) adalah sebagai berikut: 
$ echo *
case.shtml escape.shtml first.shtml 
functions.shtml hints.shtml index.shtml
ip-primer.txt raid1+0.txt  
$ echo *txt 
ip-primer.txt raid1+0.txt 
$ echo "*"
*
$ echo "*txt"
*txt



Pada contoh pertama, * berarti semua file di dalam direktori aktif. Pada contoh kedua, *txt berarti semua file yang berakhiran txt. Pada contoh ketiga, ditempatkan * di dalam petik ganda dan ini diinterpretasikan secara literal. Pada contoh ke-4, sama dengan contoh ke-3, hanya * disambung dengan string txt. 
Namun, ",  $,  `,  dan  \ masih diterjemahkan oleh shell, bahkan saat ada di apit oleh petik ganda. Karakter backslash (\) dapat digunakan untuk menandakan karakter-karakter khusus ini sehingga tidak diterjemahkan oleh shell, tetapi dilewatkan langsung kepada perintah yang akan dijalankan (misalnya echo). Sehingga untuk menampilkan string (misal nilai $X adalah 5): 
A quote is ", backslash is \, backtick is `. A
few spaces are and dollar is $. $X is 5. 
Kita harus menulis:
$ echo "A quote is \", backslash is \\, backtick is \`."
A quote is ", backslash is \, backtick is `.
$ echo "A few spaces are ; dollar is \$. \$X is ${X}."
A few spaces are ; dollar is $. $X is 5.
Kita telah melihat kekhususan dari " untuk memastikan spasi dalam teks. Tanda dollar juga khusus karena menandai suatu variabel, sehingga $X digantikan oleh shell dengan isi dari variabel X. Backslash bersifat khusus karena menandakan karakter khusus lain. Perhatikan pemanfaatan karakter escape di bawah ini: 
$ echo "This is \\ a backslash"
This is \ a backslash 
$ echo "This is \" a quote and this is \\ a backslash"
This is " a quote and this is \ a backslash 
Jadi backslash sendiri harus di-escape-kan untuk dapat ditampilkan. 

Tidak ada komentar:

Posting Komentar