Pazartesi , 24 Şubat 2020

Linux Komut İpuçları

İşletim sistemini komut satırından kullanmak çok daha hızlı ve güçlüdür. İşletim sistemine komut verip yönetmek için bir shell kullanılır. Kabuğun girdileri almak için klavyeye ve çıktıları basabilmek için ekrana ihtiyacı vardır. Modern sistemlerde terminal emulator’lar bu işlevi yerine getirmektedir. Tarihsel olarak console adı verilen, klavye ile monitörden oluşarak seri porttan bilgisayara bağlanan özel tip terminaller de vardır. Modern sistemlerde komut satırından başlatılan Linux’ta Alt+F1, Alt+F2 komutları ile sanal konsollar arasında geçiş yapılabilir.

Popüler Linux dağıtımlarında shell olarak genellikle bash veya sh kullanılır. Kullanıcılar sistemde bulunan farklı shell’lerde istediğini seçebilir. Sistemde bulunan bütün kabuklar /etc/shells dosyasında bulunur ve kullanılmak istenilen default shell /etc/passwd dosyasından ayarlanabilir. Aşağıdaki resimde flood kullanıcısı için shell /bin/sh, vagrant kullanıcısı için ise /bin/bash olarak ayarlanmıştır. Çalışırken shell değiştirmek için geçiş yapılmak istenen shell’in ismi yazılabilir.

Shell kullanıcının günlük yapacağı işlemleri kolaylaştırır. Örneğin terminali her açışımızda dosya sisteminde çalışma klasörü olarak kullanıcının $HOME klasörüne gidip komutları beklemeye başlar. bash kabuğunda kullanıcının $HOME klasörünün altındaki .bashrc dosyasının sonuna kabuk başlatılırken yapılması istenenler eklenebilir. Değişikliklerin mevcut kabukta da uygulanması için source .bashrc komutu kullanılabilir. Aşağıda kabuğun başlaması istenen klasör /home/vagrant yerine /vagrant olarak değiştirilmiştir.

bash ve diğer kabuklar kullanıcının işletim sistemi ile iletişime geçerek program çalıştırması, çalıştırılan programın ekran çıktılarının gösterilmesi, kullanıcıdan programın çalışması sırasında girdi alabilmesi, programlara argüman geçirilmesi, ortam değişkeni (Environment Variable) aktarılması, başlatılan programın parent prosesi olarak çıkış kodunun raporlanmasını sağlarlar. Kabuk sıralanan bu işlemleri yapabilmek için çekirdeğe sistem çağrıları (system call) yapar dolayısıyla Linux çekirdeği ile kullanıcı arasında köprü kurar.

Kabukta tanımlı olan ortam değişkenleri env veya printenv komutu ile ekranda görüntülenebilir. Aşağıda benim test sistemimdeki bash kabuğunda bulunan ortam değişkenleri gösterilmiştir.

Yukarıdaki ekran görüntüsünde $SHELL değişkeninde kullanıcının kullandığı kabuğu, $HOME değişkeninde kullanıcının ana dizini, $USER değişkeninde kabuğa bağlı olan kullanıcı adı görülebilir.

Yine yukarıdaki ekran çıktısındaki $PATH değişkeni üzerinde durulmaya değerdir. Bu değişken dosya sisteminde bulunan çalıştırılabilir dosyaların klasörlerini içermektedir. Kabukta dosya sistemindeki tam yolunu vermeden ls yazdığımız zaman, kabuk PATH’te bulunan klasörlere teker teker bakarak içlerinde ls ismi ile çalıştırılabilir bir dosya olup olmadığına bakar, ilk bulduğu çalıştırılabilir dosyayı çalıştırır ve diğer klasörlere bakmaz. Aşağıda $PATH değişkeninin başına mevcut klasör eklenip klasörde bulunan dosyalar $PATH’e eklenmiştir.

PATH değişkeninde olmayan bir klasördeki çalıştırılabilir bir dosyayı çalıştırabilmemizin tek yolu o dosyanın dosya sistemindeki tam veya relatif yolunu sağlamaktır. PATH içinde bulunmayan /app klasörünün içindeki booking-generator programını çalıştırmak için kabuktan /app/booking komutunu verilir. Aynı şekilde içinde bulunulan klasördeki billing adlı programı çalıştırmanın yolu da ./billing olacaktır. İkinci örnekte bulunan . o an içinde bulunulan klasörü ifade eder. .. ise bir üst klasöre gitmek için kullanılır.

Son olarak kabuğun ve çalıştırılabilir programın Linux çekirdeğine yaptığı bütün sistem çağrılarını görebilmek için strace komutu kullanılabilir. İlerleyen flood’larda detaylı olarak ele alacağımız bu aracı $PATH’in nasıl çalıştığını gözlemlemek için kullanalım.

which ls komutunu vererek sistemde bulunan ls programının dosya sistemindeki tam yolu bulunabilir. Bu komutu strace ile vererek bash’in $PATH değişkeninde bulunan klasörlerde ls dosyasını teker teker aradığı görülebilir. Aşağıdaki çıktıda bu davranış gösterilmiştir.

Yeni bir dosya oluşturmak için touch komutunu kullanırız. touch aynı zamanda bir dosyanın içeriğini değiştirmeden access, modify ve change zamanını değiştirmekte de kullanılır. Bir dosya ile ilgili bilgiler stat ile görüntülenir. Aşağıda bu kullanımlar örneklendirilmiştir.

touch komutu ile dosyaların modify zamanını güncellenerek  make, gradle, msbuild vb araçların kaynak dosyaların değiştiğini düşünmeleri ve kaynak kodları yeniden derlemeleri (rebuild) sağlanabilir.

Bir dosyanın içeriğini döktürmek için cat komutu kullanılır. cat ekrana sadece yazılabilir (printable) karakterleri basar. Yazılamayan karakterleri de bastırmak için -v, satır sonlarını $ ile ayırmak için -E ve bütün karakterleri görmek için -A kullanılır.

Metin (text) dosyaları için Linux ve macOS satır sonunu belirlemek için LF – Line Feed, Windows ise hem LF hem de CR – Carriage Return karakterlerini kullanır. Pek çok program işletim sistemlerindeki bu ayrımı tolere etse de bazı durumlarda dönüşüm yapmak gerekebilir. VS Code, Notepad++ gibi editörler dosyaların satır sonu karakterleri arasında dönüşüm yapabilmektedir. Linux ve macOS komut satırında ise unix2dos aracı ile LF -> CRLF ve dos2unix aracı ile de CRLF -> LF dönüşümü yapılabilir. Aşağıda dos2unix örneklenmiştir.

cat bütün dosyanın içeriğini göstermek için kullanılırken dosyanın başından ve sonundan birkaç satır görmek istediğimiz durumlarda sırasıyla head ve tail komutları kullanılır. head ve tail komutlarına kaç satır görmek istediğimizi parametre olarak geçeriz.

Bu bilgiler ışığında cat > new-file komutunu vererek dosya içeriğini yazmamız ve sonunda yazacaklarımızın bittiğini bildirmek yani dosyanın sonunun geldiğini belirtmek için ctrl+d’ye basmamız yeterlidir. Aşağıda bu yöntem kullanılarak bir dosya oluşturulması gösterilmiştir.

Komut satırında içerik ile birlikte dosya yaratmayı otomize hale getirmek (ctrl+d vermeden yapabilmek) için HEREDOC sentaks kullanılabilir. Bu sentaksta EOF olarak ctrl+d’nin yerine kullanılmak üzere bir magic string belirlenerek << operatörünün sağına yazılır.

> operatörü sağındaki dosya mevcut değilse yeni bir dosya yaratır mevcutsa yeni içeriği eskisinin üzerine yazar. Dosyaya ekleme yapmak istediğimizde (append) >> operatörünü kullanabiliriz.

> operatörü ile çıktıyı nasıl yönlendirebileceğimizi gördük. Şimdi de < operatörü ile girdiyi stdin yani klavye yerine bir dosyaya yönlendirelim. Bunun için aşağıdaki kullanıcıdan iki sayı alan ve bunları toplayıp ekrana basan programı kullanacağız.

Aşağıdaki çıktıda program öncelikle manuel olarak çalıştırılarak girdiler klavyeden verilmiş, daha sonra da sum-numbers-input adında bir dosya oluşturularak programın stdin’i bu dosyaya yönlendirilmiştir.

echo komutunu ekrana bir mesaj yazdırmak istediğimizde kullanırız. > operatörü ile echo programının çıktısını bir dosyaya yönlendirirsek çıktı dosyanın içeriği olacaktır. >> operatörü ile yönlendirme yapılırsa da çıktı dosyanın sonuna eklenecektir.

İki dosyanın içeriğini birleştirmek ve yeni bir dosya oluşturmak için cat komutu ve > operatörleri aşağıdaki gibi kullanılabilir. Basitçe yorumlanacağı gibi cat kendisine girdi olarak verilen dosyaları döktürmüş, > operatörü de akışı bir dosyaya yönlendirmiştir.

Son olarak stderr yani standart hata akışını bir dosyaya yönlendirmek için 2> operatörü kullanılır. Hata akışını görmek istemediğimiz programların çıktılarını /dev/null adlı özel dosyaya yönlendirerek ekrana basılmalarını engelleyebiliriz. Örneğin: my-prog 2> /dev/null.

Aşağıda cat, sort, head ve tail komutları ile farklı işlemler yapılmıştır.

Yukarıdaki örneklere benzer şekilde pipe kullanarak, verilen bir CSV dosyasındaki başlık kısmından sonraki ilk satırı ekrana bastırmak istediğimizi varsayalım. Komutların aşağıdaki şekilde kullanılması ile bu amaca kolayca erişilebilir.

Pipe ile farklı komutlara aktarılan akışlar (stream), yönlendirme operatörleri ile dosya sistemindeki bir dosyaya ya da bir aygıta aktarılabilir. Aşağıda bir önceki örnekte verilen CSV dosyasının SHA-1 hash’i hesaplanarak farklı bir dosyaya aktarılmıştır.

Şimdi pipe operatörü ile birlikte kullanılabilecek bazı faydalı komutları incelemeye başlayalım. wc – word count komutu bir metin dosyası içindeki kelime, satır, bayt ve en uzun satırdaki kolon sayısını göstermeye yarar. Aşağıda bu komut örneklenmiştir.

Bir komutun çıktısını hem başka bir komuta vermek hem de ekrana yazdırmak istediğimizde tee komutunu kullanabiliriz. Örneğin, birkaç pipe yardımıyla işlenen bir akışı hem bir dosyaya yazarak saklamak hem de sonucu doğrulamak üzere ekranda göstermek için tee kullanılabilir.

tr – translate komutu metin akışları içinde karakter değiştirme ve silme işlemleri için kullanılır. tr, akışları stdin yani standart girdiden okuyarak stdout’a yani standart çıktıya yazar. Aşağıda tr’nin değişik kullanım alanları örneklenmiştir.

more terminal ekranına sığmayacak büyüklükteki text dosyalarını sayfa sayfa göstermeye yarar. less, more ile aynı amaç için kullanılır ancak more’un aksine kullanıcının bir önceki sayfaya dönmesi ve birçok başka özelliğe imkan tanır. Aşağıda more komutu örneklenmiştir.

İlk örneklerden görüldüğü üzere sort komutu bir metin dosyasındaki girdilerin sıralanmasını sağlar. uniq komutu ise bir akışta üst üste tekrarlayan satırları tek bir satıra indirerek gösterir. Aşağıda sort ve uniq komutları örneklenmiştir.

grep komutu bir akış içerisinde kalıp ya da kalıpları (pattern) aramaya yarar. /etc/passwd dosyası içerisinde root geçen satırları ekrana bastırmak için grep root /etc/passwd, içinde root geçmeyen satırları ekrana bastırmak içinse grep -v /etc/passwd kullanılır.

grep komutu kullanılarak bir dizin ve altındaki bütün dizinlerde bulunan metin dosyalarında bir kalıp aranabilir. Bunun için grep -r <text_pattern> <folder> komutu verilebilir. Aşağıdaki ekran çıktısında /home/vagrant klasörü altında lorem metni aranmıştır.

grep’i daha güçlü kılan özelliği, metin dosyaları içinde kelime veya kelime gruplarını aramasının yanında düzenli ifadeler (regex) kullanılarak da arama yapılmasına izin vermesidir. regex’i ilerleyen flood’larda grep’teki kullanımı ile birlikte inceleyeceğiz.

find komutu kullanılarak bir dizin altındaki bütün klasörlerde bir dosya veya dizin aranabilir. Aşağıda find komutunun değişik kullanım alanları (bir dizindeki bütün dosyaları ve dizinleri arama, dosyaları isimle arama, vb) örneklenmiştir.

Anlık olarak işletim sistemi kaynaklarının hangi prosesin ne kadar kullandığını görmek için top komutu kullanılabilir.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir