UNIX Dilinde Konuşma, Bölüm 7: Komut satırı deyimleri

0
butch
IBM Türkiye ve Fazlamesai.net işbirliği ile dilimize kazandırılan yeni bir IBM developerWorks makalesi ile karşınızdayız. Diğer makalelere buradan ulaşabilirsiniz.

Makalenin özgün haline bu adresten ulaşabilirsiniz.

UNIX Dilinde Konuşma, Bölüm 7: Komut satırı deyimleri

UNIX sözcük bilginizi genişletin

Düzey: Orta

Martin Streicher (martin.streicher@linux-mag.com), Şef Editör, Linux Magazine

06 Şubat 2007

UNIX® kendine ait bir dile sahiptir ve komut dağarcığı oldukça geniştir. Ancak, her şeyi bir defada öğrenmenize gerek yok. Burada, daha fazla komut satırı bileşimlerini keşfetmeniz ve UNIX diline hakimiyetinizi genişletmeniz amaçlanmaktadır.

Yabancı bir ülkeye seyahat ettiğinizde, o ülkede yaşayan insanlar bilmediğiniz bir yerel dil konuşuyorlarsa, kendinizi "Bunun fiyatı ne?", "Bu ne eti?" ve "Lavabo nerede?" gibi hayat kurtaracak sözlerle güvenceye alabilirsiniz. Bu tür küçük hazır cümleleri ezberlemek, siparişini verdiğiniz yılanlı sandviç için fazla ücret ödememenizi ve Tabiat Ana (ya da yılanlı sandviç) çağırdığında nereye gideceğinizi bilmenizi sağlar.

UNIX® de kendine has bir dile sahiptir ve geçtiğimiz altı ay içinde, bu UNIX Dilinde Konuşma serisi, komut satırı dili konusunda yoğun bir kurs sağladı. Bu ay, yerlilerin arasına hemen karışmanızı sağlayacak bazı yardımcı sözcük gruplarını öğreneceksiniz. Diş fırçanızı alın, rahat bir çift ayakkabıyı ayağınıza geçirin ve aşılarınızı olun. Güneşe, kuma ve deniz kabuklarına gidiyorsunuz. (Güneş ve kum için taşınabilir bilgisayarınızı toplayın, plaja gidin, suyun kenarında oturup bu yazıyı okuyun. Ve güneş kreminizi unutmayın.)

Yürüyüş turuna katılın

Önceki UNIX Dilinde Konuşma makalelerinin birçoğunda (bkz. Kaynaklar), dosyaları ve hatta tüm UNIX dosya sistemini taramak ve işlemek için paha biçilemez bir yardımcı program olan find komutu anlatılmıştı. Örneğin, ben genellikle çok sayıda dosyayı işlemek için find komutunu, grep ya da Perl ile birlikte kullanırım. Geniş bir kod bütününde bir değişkenin ya da sabit değerin nerede tanımlandığını bilmeniz mi gerekiyor? Aşağıdaki komutu deneyin:


$ find /path/to/src 

 -type f | xargs grep -H -I -i -n 

string

            


Komutun çıkışı, satır numarası ve eşleşen özel metnin yer aldığı, string'i (dize) içeren dosya adlarının bir listesi olur. -H seçeneği, her bir eşleşmeyi, dosya adıyla ve -n, her bir eşleşmeyi satır numarasıyla başlatır. -i seçeneği, büyük/küçük harfin dikkate alınmamasını sağlar. -I (büyük "I"), ikili dosyaları atlar.

Daha önce xargs komutunu görmediyseniz, belirlediğiniz komutu (burada, listelenen tüm seçeneklerle grep komutu), standart giriş ile sağlanan her bir bağımsız değişken için bir kez çalıştırır. /path/to/src dizininin a, b ve c dosyalarını içerdiğini varsayarsak, find ile xargs komutunu birlikte kullanmamız aşağıdakine eşdeğer olacaktır:


grep -H -I -i -n string a

grep -H -I -i -n string b

grep -H -I -i -n string c




Aslında, bir dosya koleksiyonunda arama yapmak o kadar yaygın bir şeydir ki grep komutunun, bir dosya sistemi hiyerarşini yinelemek için kendi seçeneği vardır. -d recurse ya da eşanlamlıları olan -R ya da -r seçeneğini kullanın. Örneğin:


$ grep -H -I -i -n -R string



                /path/to/src

            


Bu komut, find/xargs ile aynı işlevi görür. (Dosyalarla ilgili birçok UNIX yardımcı programının yineleme için seçenekleri olduğunu göreceksiniz. ls -R, özyinelemeli olarak bir hiyerarşinin içeriğini listeler. chmod, chgrp ve chown, mod, grup ve sahiplik değişikliklerini tüm dosya sistemi hiyerarşisine uygulamak için -R seçeneğini kullanır. chmod -R komutunu kullanırken dikkatli olun. chmod -R a-x komutunda olduğu gibi bir dizinin yürütme bitlerini kaldırırsanız, yanlışlıkla dizini kullanılamaz hale getirebilirsiniz. Daha seçici olmak için find . -type f | xargs chmod a-x komutunu deneyin.)

Peki, ne zaman find/xargs, ne zaman grep komutunu kullanmalısınız? find komutunu kullanırken ne zaman seçici olmanız gerekir? find komutunun, belirli gereksinimleri karşılayan dosyaları seçmenize olanak tanıyan birçok koşulu vardır; "Ali'nin sahip olduğu ve geceyarısından sonra değiştirilen tüm düzenli dosyalar" kavramsalı gibi. Aksi halde, grep -R yeterli olacaktır.

Başka bir yardımcı program, find komutunu kullanmaktan daha kullanışlı ve hızlı olabilir. Bir dosyayı adına göre bulmaya çalışıyorsanız, find -name yerine locate komutunu deneyin. locate komutu, sisteminizdeki her dosyayı belirli aralıklarla (sistem yöneticinizin yaptığı ayara bağlı olarak günde bir kez, vb.) sınıflandırır ve yollar ile dosya adlarının yer aldığı bir veritabanı oluşturur. locate komutunu çalıştırdığınızda, özel veritabanını tarayarak eşleşmeler oluşturmayı dener.

Örneğin, locate '*.1' sorgusunu çalıştırdığınızda, adları .1 ile biten tüm dosyalar ve dizinler verilir. (Baştaki yıldız işareti eşleşen her şey anlamına gelir.) Kolaylık olması açısından, locate fish komutu ile locate '*fish*' birbirinin aynıdır.


Para birimi değişimi

Birçok UNIX yardımcı programı dosyaları değiştirir. Çoğu durumda, değiştirilen içerik, standart çıkışa gönderilerek, sonuçları yeniden yönlendirme işleçleriyle daha ayrıntılı bir şekilde işlemeniz (dikey çubuk kullanma, |) ya da yakalamanız (> ya da >> işleçleri) sağlanır.

Diğer yardımcı programlar, genellikle bir defada birçok dosyayı işleyebilen, koruma amacıyla özgün dosyayı tutabilen ve değişen içerik için yeni bir dosya oluşturan yardımcı programlardır. Örneğin, bir dosyayı işlemek için komut satırından doğrudan Perl dizinini kullanabilirsiniz. Şu komut:


$ perl -i.bak -pe 's/\bdollar(s?)/buck\1/g' file.txt


"dollar" sözcüğünü "buck" ve "dollars" sözcüğünü "bucks" sözcüğüyle değiştirir. perl -i komutu, mevcut file.txt dosyasını değiştirir; perl -i.bak, özgün dosyanın bir kopyasını oluşturur ve özgün dosyayı, yeni değiştirilmiş sürümden ayırt etmek için sonuna bir .bak soneki ekler. Dolayısıyla, aşağıdaki gibi bir komut:


perl -i.bak -pe 's/\bdollar(s?)/buck\1/g' *


geçerli dizinde her dosya için bir yedek oluşturur. file1.txt, file2.txt ve file3.txt dosyalarınız olsaydı, file1.txt.bak, file2.txt.bak ve file3.txt.bak dosyalarınız olurdu. Hatalar olabilir, dolayısıyla bir yedek oluşturmak akıllıca bir davranıştır.

Bir hata yaparsanız ve özgün dosyayı kurtarmanız gerekirse, aşağıdakini yazmanız yeterlidir:


mv file1.txt.bak file1.txt


Ancak, yeniden adlandırılacak yüzlerce dosyanız varsa ne olacak? Elbette, yüzlerce ayrı mv komutu yazmak istemezsiniz. Bunun yerine, aşağıdakini yazabilirsiniz:

foreach file in (*.txt)

do

  mv $file.bak $file

done




Bu komut, buradaki gibi basit durumlarda işe yarar. Ancak, bu tür görevler çok yaygın olduğu için özel bir yardımcı program işi daha da hızlı gerçekleştirmektedir. Şu komut:


$ rename 's/\.bak$//' *.bak


aynı görevi gerçekleştirir. s/\.bak$// düzenli ifadesi, komut satırında listelenen her bir dosya adından (burada * ya da every file) .bak sonekini kaldırır ve kısaltılmış adı, hedef dosya adı olarak kullanır.

rename komutu, özellikle dosya adları düzensiz olduğunda çok işe yarar. Örneğin, okula yeni başlayan bir öğrenin yazdığı harflerin toplamına benzeyen bu dizinin içeriğini düşünelim.


$ ls RenT.txt  bEErMoNey.txt  gASmoNey.TXt


Yukarıda gösterilen foreach komut dosyası, dosya adları çok düzensiz olduğu için bu sorunun üstesinden gelebilir. Yine de rename, birkaç tuş vuruşuyla işlemi gerçekleştirebilir:


$ rename 'y/A-Z/a-z/' *


y/A-Z/a-z/ düzenli ifadesindeki y işleci, çeviri için kullanılmıştır. Çeviri iki liste gerektirir: Özgün karakterler listesi ve değiştirilecek karakterlerin listesi. İki listenin de boyutu aynıysa, metindeki özgün listenin ilk karakterin her örneği, değişim listesindeki ilk karakterle değiştirilir. Diğer bir deyişle, örnekte, büyük "A" harfinin her örneği, küçük "a" harfiyle, "B" harfi "b" ile, vb. şekilde değiştirilir.  Metindeki küçük harfler değiştirilmeden bırakılır.

rename komutunun yapacaklarını önizlemek için komuta -n seçeneğini ekleyin. Bu seçenek, gerçek değişiklikleri yapmadan komutun eylemlerini gösterir:


$ rename -n 'y/A-Z/a-z/' *

RenT.txt renamed as rent.txt

bEErMoNey.txt renamed as beermoney.txt

gASmoNey.TXt renamed as gasmoney.txt

$ rename 'y/A-Z/a-z/' *

$ ls

beermoney.txt  gasmoney.txt  rent.txt


Dikkat edilmesi gereken bir nokta: UNIX sistemlerinde, dosya adları büyük/küçük harfe duyarlıdır. Bir dizinde, Aa.Txt ve aA.txT dosyaları bulunabilir. Yukarıda gösterildiği gibi büyük/küçük harfe duyarlı dosyaları, küçük harfli dosya adlarına dönüştüren bir kural yazmak mümkündür; böylece, önceden benzersiz olan dosya adları arasında çakışmalara neden olunabilir. Bu durumda rename komutunun işlevi nedir? Görelim:


$ rename -n 'y/A-Z/a-z/' * 

Aa.Txt renamed as aa.txt

aA.txT renamed as aa.txt

$ rename 'y/A-Z/a-z/' *

aA.txT not renamed: aa.txt already exists

$ ls

aA.txT  aa.txt


Yeniden adlandırma işlemi ilerlerken var olan dosyaları iyice değiştirmek istiyorsanız, -f işaretini ekleyin. Bu örnekte, sonuç aa.txt adlı bir dosya olur. Peki, bu önceden hangi dosyaydı? rename, alfabetik sırayla çalıştığından, sonraki aA.txT dosyası artık aa.txt olmuştur. Neden -f seçeneğini kullanmalıyız? İki dosya, adları dışında birbirinin aynıysa, rename -f komutu kopyaları kaldırır.


Zaman, kaybetme zamanı değil

UNIX kullanımının büyük bir kısmını dosya yönetimi oluşturur. Sistemde sayısız yapılandırma dosyası vardır. Gerekenden çok daha fazla veri dosyasına ve kişisel dosyaya sahip olabilirsiniz. Zaman zaman, yanlışlıkla değerli bir dosyayı kaldırabilir veya dosyanın üzerine yazabilirsiniz. Kabuk ve yönetim yardımcı programları, felaketi önlemenize yardımcı olabilir.

Kabuk komut istemine aşağıdaki komutları yazın. Bu komutlar bash içinde çalışır, ancak zsh ve diğer kabuklardakine benzer seçenekleri vardır.


$ alias mv=mv -i

$ alias rm=rm -i

$ set -o noclobber




İlk iki komut, komut satırında mv -i ile mv ve rm -i ile rm komutunun yerine geçer. Etkileşimli mod, sizi işleminizi onaylamaya zorlar.

Üçüncü komut, güvenliğin bir kısmını kabuğun kendi içinde sağlar. noclobber etkin durumdayken, > yeniden yönlendirme işlecini kullanarak yanlışlıkla bir dosyanın üzerine yazamazsınız:


$ ls

secret.txt

$ cat > secret.txt

bash: secret.txt: cannot overwrite existing file


noclobber işlevini devre dışı bırakmak için aşağıdakileri yazın:


set +o noclobber


Ayrıca, istediğiniz zaman >| (bir büyüktür işareti ve ardından bir dikey çubuk) yeniden yönlendirme işlecini kullanarak bir üzerine yazma işlemini de zorlayabilirsiniz.

$ cat secret.txt

I love green eggs and ham. 

$ echo "No more secrets" >| secret.txt

$ cat secret.txt

No more secrets





Yerel halkın sırları

Bir kenti gerçekten keşfetmek istiyorsanız, yerel meyhaneleri ziyaret etmelisiniz. İşte size Zagat'ta yer alabilecek bir komut satırı bileşimleri koleksiyonu.

mkdir -p, hızlı bir hiyerarşi oluşturma çalışması yapar. -p seçeneği ile mkdir komutu, belirtilen yolda bulunan her bir dizini ve alt dizini oluşturur:


$ mkdir -p make/many/directories/at/once

$ ls -R 

./make:

many



./make/many:

directories



./make/many/directories:

at



./make/many/directories/at:

once



./make/many/directories/at/once:


Bir sonraki ödeme gününüzün ne zaman olduğunu bilmek isterseniz, cal komutunu yazmanız yeterlidir. Hiçbir bağımsız değişken olmadan, yalnızca cal komutu, içinde bulunduğunuz aya ilişkin takvimi yazdırır. cal -3 komutu önceki, içinde bulunduğunuz ve sonraki ayı; cal 06 2009 komutu da Haziran 2009 ayını gösterir. (Doğum günüm o yıl Pazartesi gününe geliyor!)


$ cal



   November 2006    

Su Mo Tu We Th Fr Sa

          1  2  3  4

 5  6  7  8  9 10 11

12 13 14 15 16 17 18

19 20 21 22 23 24 25

26 27 28 29 30

$ cal 06 2009



     June 2009      

Su Mo Tu We Th Fr Sa

    1  2  3  4  5  6

 7  8  9 10 11 12 13

14 15 16 17 18 19 20

21 22 23 24 25 26 27

28 29 30


UNIX'te çok sayıda komut olduğu için tüm yardımcı programların tüm seçeneklerini hatırlamak gerçekten imkansızdır. Aslına bakarsanız, bazen yardımcı programın adını bile hatırlamayabilirsiniz.

Şaşkına döndüğünüzde man komutunu girin. Örneğin, man komutunun nasıl kullanılacağını öğrenmek için man man komutunu girin. man rm ve man mv komutlarını kullanarak rm ve mv için hazırlanan açıklamaları da görebilirsiniz. Ayrıca, aradığınız konuyu biliyorsanız, bu konuyla ilgili man sayfalarının bir listesini bulmak için make -k komutunu kullanabilirsiniz.


$ man -k cron

cron (8)             - daemon to execute scheduled commands (Vixie Cron)

crontab (1)          - maintain crontab files for individual users (V3)

crontab (5)          - tables for driving cron

dh_installcron (1)   - install cron scripts into etc/cron.*


Burada, man komutu, tek satırlık açıklamaları cron sözcüğünü içeren yardımcı programların man sayfalarını buldu. Büyük olasılıkla, bu man sayfalarında sistem işi zamanlama yardımcı programı olan cron'un nasıl kullanılacağı anlatılmaktadır.

Peki, bu küçük sayılar ne için kullanılıyor? Her bir sayı, çevrimiçi UNIX kılavuzundaki bir bölümü belirtir. Bölüm 1, bir UNIX kullanıcısının kabukta çalıştırabileceği tüm komutlar için ayrılmıştır. Bölüm 5'te dosya biçimleri anlatılır. Bölüm 8'de sistem yönetimi komutları yer alır. Diğer bölümler, sistem çağrılarını (2), kitaplık çağrılarını (3) ve diğer konuları içerir.

Gördüğünüz gibi, çoğu komut bir tür çıkış sağlar. Çoğu komut satırı komutları, sonuçlar için standart çıkışı (stdout) kullanır. Ancak bazıları, standart çıkışı ilerlemeyi ve standart hatayı (stderr) da hata iletilerini göstermek için kullanır. Sık sık komut satırıyla çalışmaya müdahale ettiği için oldukça yararlı olan bu tür bir çıkışı dikkate almak istemezseniz, çıkışınızı UNIX bit sepetine (/dev/null) yeniden yönlendirebilirsiniz. Bitler iade edilir, ancak kullanıma alınmaz.

Aşağıdaki basit örneği inceleyin:


$ ls

secret.txt

$ cat secret.txt

I am the Walrus.

$ cat secret.txt > /dev/null

$ cat socrates.txt > /dev/null

cat: socrates.txt: No such file or directory

$ cat socrates.txt >& /dev/null

$ echo Done.

Done.


cat komutunun standart çıkışını /dev/null dizinine yönlendirirseniz, hiçbir şey görüntülenmez. Bunun nedeni, tüm bitlerin  sanal "kalıcı dikey dosyaya" atılmış olmasıdır.   Ancak, bir hata yaparsanız, standart çıkışta sağlanan hata iletileri görüntülenir. Tüm çıkışı dikkate almamayı seçerseniz, stdout ve stderr çıkışlarını bit sepetine göndermek için >& işlecini kullanın.

/dev/null dizinini, var olan dosyaları boşaltmak ya da yeni, boş dosyalar oluşturmak için sıfır uzunluklu bir dosya olarak da kullanabilirsiniz:


$ cat secret.txt

Anakin Skywalker is Darth Vader. 

$ cp /dev/null secret.txt

$ cat secret.txt

$ echo "The moon is made of cheese!" > secret.txt

$ cat secret.txt

The moon is made of cheese!

$ cat /dev/null > secret.txt

$ cat secret.txt

$ cp /dev/null newsecret.txt

$ cat newsecret.txt

$ echo Done.

Done.


Bu arada, UNIX'i bir Macintosh makinede kullanırsanız, Terminal penceresinde open komutunu deneyin. Örneğin, geçerli çalışma dizininde poodle.jpg adlı bir dosya varsa, open poodle.jpg komutu yerleşik Mac OS X resim görüntüleyicisi olan Preview uygulamasını başlatır ve kanişinizin resmi görüntülenir. Mac OS X open komutu, komut satırı ile Macintosh'un pencere ortamı arasında var olan harika bir bağlantıdır ve genellikle, Finder uygulamasını yeniden sıralamaktan çok daha hızlıdır.


Yeniden gelmeniz gerekiyor!

Vay! Oldukça yoğun bir sınıf oldu, ama artık UNIX'te daha da ilerilere gitmeye hazırsınız. Tabiat Ana çağırdığında, bit sepetini nerede bulacağınızı bile biliyorsunuz.

Her zaman olduğu gibi anlatılacak daha çok şey var. Önümüzdeki aylarda, UNIX Dilinde Konuşma serisinde iş denetimi, düzenli ifadeler (kesinlikle garip bir dil, ancak hakim olması imkansız değil), Internet'ten yüklediğiniz yeni yardımcı programların nasıl oluşturulacağı ve daha birçok konu araştırılacaktır.

Güneş kreminizi unutmayın.

Kaynaklar

Bilgi Edinme

Ürün ve teknoloji edinme
  • IBM deneme yazılımı: developerWorks'deki yazılımı doğrudan yükleyerek bir sonraki geliştirme projenizi oluşturun.


Tartışma


Yazar hakkında

Martin Streicher'in

fotoğrafı

Martin Streicher, Linux Magazine adlı dergide Şef Editör, bir Web geliştiricisi ve developerWorks topluluğuna düzenli katkıda bulunan bir katılımcıdır. Streicher, Purdue University'den bilgisayar bilimi konusunda bir Master derecesi almıştır ve 1986 yılından bu yana UNIX benzeri sistemlerde programlama yapmaktadır. Martin Streicher'a martin.streicher@linux-mag.com adresinden erişebilirsiniz.

Görüşler

0
deneme101
cal programı hakkında küçük bir yorumda bulunmak istiyorum:

Web sayfalarında 'cal' programından tarihleri düzenli bir biçimde göstermek için oldukça yararlanılıyor.

Özellikle scriptin yolunu browserdan açık bir şekilde düzenlediğimizi düşünürsek:

http://www.adres.com/cgi-bin/refcal?2008

buradaki refcal scripti 2008 değerini alıyor ve calc programına gönderiyor. Eğer scriptin yazarı istenilen önlemi almaz ise yani 2008 yılından gelen veriyi şu şekilde kontrol etmez ise:

if ($year && ($year =~ /^\\s*\\d+\\s*$/)) {
#burada $year değişkeni ile istenilen yapılabilir
}else {
print "Hata oluştu $year değişkeni istenilen gibi değil.";
}

Şu şekildeki bir adres satırı istenilmeyen sonuçlar doğuracaktır.

http://www.adres.com/cgi-bin/refcal?2007;cat+/etc/passwd

Bu sadece 'cal' programına has bir durum değil.

PHP'deki, system(),shell_exec(),passthru() ve exec() fonksiyonları,Perl'deki ve Python'daki bu programların denkleri bilgisayar korsanları için vazgeçilmez açık kapılarıdır.Çünkü bu fonksiyonlar ile serverdaki programlara erişim sağlayabilirler.

Kısaca, server tarafında program çalıştıran fonksiyonlar her zaman bu açığı verirler; yapmamız gereken gelen verinin istediğimiz şekilde olup olmadığını kontrol etmekdir.
0
rr
hocam `escape shell args´ benzeri fonksiyonlar bütün programlama dillerinde mevcuttur
gelen parametreyi cal programına bodozlama verirsen tabi alırsın eline
0
deneme101
'escape shell args' deyince regular expressions'dan mı bahsediyorsun? Biraz daha açıklayıcı olabilir misin?
Görüş belirtmek için giriş yapın...

İlgili Yazılar

UNIX Dilinde Konuşma, Bölüm 6: Her şeyi otomatikleştirin!

butch

IBM Türkiye ve Fazlamesai.net işbirliği ile dilimize kazandırılan yeni bir IBM developerWorks makalesi ile karşınızdayız. Diğer makalelere buradan ulaşabilirsiniz.

Makalenin özgün haline bu adresten ulaşabilirsiniz.

UNIX Dilinde Konuşma, Bölüm 2: Daha çok değil, daha akıllı çalışma

tongucyumruk

IBM Türkiye ve Fazlamesai.net işbirliği ile dilimize kazandırılan yeni bir IBM developerWorks makalesi ile karşınızdayız. Diğer makalelere buradan ulaşabilirsiniz.

Makalenin özgün haline bu adresten ulaşabilirsiniz.

Ajax ve XML: Beş adet çok iyi Ajax pencere bileşeni

tongucyumruk

IBM Türkiye ve Fazlamesai.net işbirliği ile dilimize kazandırılan yeni bir IBM developerWorks makalesi ile karşınızdayız. Diğer makalelere buradan ulaşabilirsiniz.

Makalenin özgün haline bu adresten ulaşabilirsiniz.

GTK+ ile ilgili temel bilgiler, Bölüm 2: GTK+ nasıl kullanılır?

butch

IBM Türkiye ve Fazlamesai.net işbirliği ile dilimize kazandırılan yeni bir IBM developerWorks makalesi ile karşınızdayız. Diğer makalelere buradan ulaşabilirsiniz.

Makalenin özgün haline bu adresten ulaşabilirsiniz.

Ajax ve XML: Beş adet kötü Ajax kalıbı

tongucyumruk

IBM Türkiye ve Fazlamesai.net işbirliği ile dilimize kazandırılan yeni bir IBM developerWorks makalesi ile karşınızdayız. Diğer makalelere buradan ulaşabilirsiniz.

Makalenin özgün haline bu adresten ulaşabilirsiniz.