21 Ağustos 2018 Salı

Go ile Komut Satırı Aracı Oluşturmak

CLI(Command Line Interface) -türkçe olarak ifade edersek komut satırı arayüzü- kullanıcıların komut satırında etkileşimde bulunduğu programdır.
Go standart kütüphanelerini kullanarak komut satırı araçları oluşturmanın basit bir yolunu sunuyor. Go'da bunu yapmanın birden çok yolu vardır ancak bu yazıda genel hatlarıyla flag paketini açıklayacağım.

Parametreleri Ayrıştırma

Ayrıştırma işleminde genel olarak kullanılan üç terim vardır; argümanlar, seçenekler ve bayraklar. Bunlar sıklıkla birbirinin yerine kullanılır.
Go bu terimler konusunda genel tanımlara uymuyor, flag paketi ile bir veya iki tire ile başlayan tüm dizgeleri bayrak olarak, kullanıcı girdisi ve tire olmayan tüm dizgeleri argüman olarak kabul ediyor. 

Flag Paketi

Flag paketi, komut satırı ayrıştırma işlemleri için kullanılan standart kütüphanedir.

Bayrakları, flag.String(), flag.Bool(), flag.Int() kullanılarak tanımlayabiliriz:

import "flag"
var ipPtr = flag.Int("bayrakAdı", 1234, "bayrakAdı için yardım mesajı")
flag.Parse()

ipPtr -bayrakAdı veya --bayrakAdı parametresi ile alınan değere referans gösterecektir. *ipPtr varsayılan değeri 1234'tür.
Bu örnekte flag.Parse() işlevi, komut satırı girişini ayrıştırır ve -bayrakAdı parametresi ile aldığı değeri *ipPtr'a yazar.

Bayrak olarak tanımlananlar birer işaretçilerdir.
Bayrağı Var() işlevi kullanarak bir değişkene bağlayabiliriz:

var ipdegeri int
flag.IntVar(&ipdegeri, "bayrakAdı", 1234, "bayrakAdı için yardım mesajı")
flag.Parse()

Kullanıcıdan aldığı cümlenin kaç kelimeden olduğunu döndüren basit bir go programı üzerinden flag paketini nasıl kullanacağımızı inceleyelim:

package main

import (
    "flag"
    "fmt"
    "os"
    "strings"
)

func main() {
    var cumle string
    flag.StringVar(&cumle, "boyut", "", "Cümlenin boyutunu döndürür.")
    flag.Parse()

    if cumle == "" {
        flag.PrintDefaults()
        os.Exit(1)
    }
    cumleBoyutu := kacKelime(cumle)
    fmt.Printf("Cumlenin kelime sayisi = %d \n", cumleBoyutu)

}

func kacKelime(cumle string) int {
    var kelimeler []string
    kelimeler = strings.Split(cumle, " ")
    return len(kelimeler)
}

Burada varsayılan değeri boş karakter dizgesi olan string türünde bir bayrak tanımlıyoruz. Eğer StringVar kullanıyorsak, değerin yazılacağı değişkenin adresini belirtmeliyiz. Son kısımda da kullanıcılara bu bayrağın ne işe yaradığını anlatmak için kullanım iletisi ekliyoruz.
Eğer kullanıcı herhangi bir parametre girmezse tanımlanan tüm komut satırı parametrelerinin kullanım iletisini yazdırır.
Eğer kullanıcı -boyut parametresi ile bir cümle yazarsa program girilen cümlenin kaç kelime olduğunu dönecektir.
Not: Programda string paketi cümleyi kelimelere bölmek, os paketi ise programın sonlanması için kullanılmıştır.
Son olarak bütün bayraklar tanımlandıktan sonra bayrakların değerlerinin atanması için flag.Parse() öğesini çağırmalıyız.

Help Çıktısı

Komut satırı aracınıza kullanıcıları nasıl çalıştıracağı konusunda yönlendiren bir mesaj eklemelisiniz. flag paketi bayrak oluştururken eklediğimiz kullanım iletilerini birleştirerek yardım metnini oluşturur.
Yardım metnini görüntülemek için:
./komutSatırıBayraklari --help
veya
./komutSatırıBayraklari -h
komutlarını kullanabiliriz.

help çıktısını kendimizde değiştirebiliriz, bunun için flag paketinde Usage işlevi bulunmaktadır.

package main

import (
    "flag"
    "fmt"
    "os"
)

func main() {
    flag.Usage = func() {
        fmt.Printf("%s programının yardım sayfasıdır.", os.Args[0])
        PrintDefaults()
    }
    flag.Parse()
}

Artık programımızı -h veya --help parametresiyle çalıştırdığımızda Usage ile oluşturduğumuz mesaj yazılacaktır.
Burada program adı yerine os.Args[0] kullanılmıştır çünkü ilk argüman her zaman programın adıdır.

Bir bayrağı zorunlu hale getirmek için:

    cumlePtr := flag.String("b", "", "Cümlenin boyutunu döndürür.(Kullanımı zorunludur.)")
    kontrolPtr := flag.Bool("k", false, "Doğru ya da yanlış değerini alır. Varsayılan değeri false.")
    flag.Parse()
    if *cumlePtr == "" {
        flag.PrintDefaults()
        os.Exit(1)
    }
    fmt.Printf("cumlePtr: %s,  kontrolPtr: %t", *cumlePtr, *kontrolPtr)

Burada -b parametresi olmadan program çalışmayacaktır.

Komut Satırından Çalıştırılabilir Hale Getirmek
$ go build gobayrak.go
Bu komut ile gobayrak adında çalıştırılabilir dosya oluşur.

$ cp gobayrak /usr/local/bin
Bu dosyayı /usr/local/bin dizinine kopyalarak programımızı komut satırından kullanabiliriz.

8 Ağustos 2018 Çarşamba

/etc/hosts Dosyası ve NSS Nedir?

Hosts Dosyası Nedir?


    Hosts dosyası makine adlarını IP adreslerine eşleyen, metin editörü ile açılıp düzenlenebilen bir işletim sistemi dosyasıdır. İnternet sitelerinin isimlerini IP adresleri ile eşleştirir de diyebiliriz.
Makine adları için statik bir tablo araması yapar.
  • Makine adlarını çözümleme işlevinde, yerel sistemlerde kullanılmak üzere hosts dosyası herhangi bir makine adını veya alan adını tanımlamak için kullanılabilir.
  • Bazı web servisleri, geliştiriciler veya yöneticiler şirketin iç kaynaklarına erişmek, bunları test etmek gibi çeşitli amaçlar için alanı sadece yerel alan ağı içinde tanımlar.
    Örneğin; sadece bir şirket içinde -şirketin yerel alan ağında- kullanılan bir panelimiz olsun. Bunu hosts dosyasında tanımlayarak bağlanabiliriz.
  • Hosts dosyası çevrimiçi reklamcılığı, casus yazılımı, reklam yazılımı veya diğer kötü amaçlı yazılımları içerdiği bilinen zararlı kaynakların ve sunucuların etki alanlarını engellemek için kullanılabilir.
  • DNS hizmetinde bir sorun, engel yada yönlendirme varsa hosts dosyasında belirli alan adlarını IP adresleriyle birlikte değiştirerek açık hale getirebiliriz.

Makine Adı ve IP Adreslerini Eşleme

    Hosts dosyası içerisinde her makine için tek satır ayrılmıştır ve bu satırların yazımı aşağıdaki formattadır:

IP_address    canonical_hostname    [aliases ...]

Dosya içerisinde;
  • her alan bir boşluk karakteriyle veya tab karakteri ile birbirinden ayrılır.
  • IP_address diye belirtilen alan, o makine adı için kullanılacak olan IP adresidir. 
  • canonical_hostname ile belirtilen alan, IP adresiyle ilişkili yerel olarak bilinen sunucu adlarını belirtir. Genel yapıya göre IP adresinden sonraki ilk alan tam nitelikli alan adıdır. Yabi bu makinenin/sunucunun resmi adıdır. 
  • aliases diye belirtilen diğer alanlar, tanımlanan IP adresi için diğer adlar veya alternatif adlardır.
  • tamamen boş satırlar yok sayılır.

 /etc/hosts düz metin dosyasıdır ve iki türde satırlara izin verilir:
  • Makine/sunucu adı tanımlaması
  • Boş satırlar veya yorum satırları
Yorum sayırları '#' ile başlamalıdır.,


Hosts Dosyasının Konumu

    Dosya sistemi hiyerarşisi işletim sistemine göre değişir. Ancak bu dosya genellikle 'hosts' olarak isimlendirir.
Unix ve Unix-benzeri sistemlerde /etc/hosts konumunda bulunur. 

Örnek hosts dosyası:

       # The following lines are desirable for IPv4 capable hosts
       127.0.0.1       localhost

       # 127.0.1.1 is often used for the FQDN of the machine
       127.0.1.1       thishost.mydomain.org  thishost
       192.168.1.10    foo.mydomain.org       foo
       192.168.1.13    bar.mydomain.org       bar
       146.82.138.7    master.debian.org      master
       209.237.226.90  www.opensource.org

       # The following lines are desirable for IPv6 capable hosts
       ::1             localhost ip6-localhost ip6-loopback
       ff02::1         ip6-allnodes
       ff02::2         ip6-allrouters



    Bazı işletim sistemlerinde hosts dosyasının içeriği, DNS gibi diğer ad çözümleme yöntemleri için kullanılır ancak birçok sistem özelleştirme sağlamak için -Linux ve Unix için nsswitch.conf gibi-  
NSS (name server switch) kullanır. Uzak DNS çözümleyicisinin aksine, hosts dosyası yerel bilgisayar yöneticisinin doğrudan denetimi altındadır.

Peki Nedir Bu NSS?

    NSS ortak yapılandırma veritabanları ve ad çözümleme mekanizmaları için çeşitli kaynaklar sağlayan Unix-benzeri işletim sistemlerinde kullanılan bir servistir. Bu kaynaklar yerel işletim sistemi dosyalarını (/etc/group, /etc/passwd, /etc/hosts gibi), DNS, NIS ve LDAP'ı içerir.
NSS bir istemcinin veya uygulamanın ağ bilgilerini nasıl aldığını kontrol eder. 
nsswitch.conf dosyası ile yapılandırılabilir.

/etc/nsswitch.conf Dosyası

    Bu dosya GNU C kütüphanesi tarafından, çeşitli kategorilerde name-service hizmeti bilgileri elde etmek için hangi kaynaklardan ve hangi sırayla alınacağını belirlemek için kullanılan düz metin dosyasıdır. Bu yapılandırma dosyası, bir işlem -hosts, users, groups gibi- hakkında bilgi içeren çeşitli veritabanlarını nasıl incelediğini kontrol eder. Her bilgi kategorisi bir veritabanı adıyla tanımlanır. 
İlk sütun veritabanı adını belirtir. Kalan sütunlar, sorgulanacak kaynakların sırasını ve arama sonucuyla gerçekleşebilecek sınırlı bir eylemler kümesini tanımlar.
Sisteminizde desteklenen servis özellikleri, paylaşılan kütüphanelerin varlığına bağlıdır ve bu yüzden genişletilebilir. Örneğin hosts veritabanı için ek olarak 'dns', passwd ve shadow veritabanları için ek olarak 'compat' seçeneği belirtebilirsiniz.

    nsswitch.conf dosyasındaki her girdi, bir veritabanı adı ve ayrılmış kaynak listesinden oluşur. Her kaynak, bir sonraki listelenen kaynağın kullanılıp kullanılmayacağını belirleyen isteğe bağlı bir sonlandırma ölçütüne sahip olabilir veya arama mevcut kaynakta sona erer.

Örnek nsswitch.conf dosyası:

           passwd:         compat
           group:           compat
           shadow:        compat

           hosts:            dns [!UNAVAIL=return] files
           networks:      nis [NOTFOUND=return] files
           ethers:           nis [NOTFOUND=return] files
           protocols:     nis [NOTFOUND=return] files
           rpc:               nis [NOTFOUND=return] files
           services:       nis [NOTFOUND=return] files