18 Haziran 2020 Perşembe

bash kodlama - array

Giriş

1. Array Tanımlamak
array tanımlamak için iki yöntem var
1. declare -a kullanmak
2. =(...) kullanmak

declare - a
Şöyle yaparız.
declare -a obj
obj+=("val1")
obj+=("val2")

for item in ${obj[@]}; do
  echo "${obj[${item}]} ${item}"
done
declare -n ile değişkene referans alınır. Şöyle yaparız.
$ spam="fred"
$ declare -n tripe=spam
$ echo $tripe
fred
$ tripe=juki
$ echo $spam
juki
2. =(...) Kullamak
Örnek
Açıklaması şöyle
You can store the current directory’s files in an array as follows:
Şöyle yaparız.
items=(*)
Örnek
Şöyle yaparız
#!/bin/bash
var=ON
cmd=( /home/username/myscript )   # create array with one element
if [ "$var" == "ON" ]; then
    cmd+=( -a )                   # append to the array
fi
cmd+=( -b 76 )                    # append two elements
3. Array Kullanmak
# Karakteri
Açıklaması şöyle
The # is often used in bash to count the number of occurrences or the length of a variable.
Dizinin Uzunluğunu Bulma-${#array[@]} Karakteri
Örnek
Şöyle yaparız.
myArr=(A B C); echo ${#myArr[@]}
Sonuç olarak 3 alırız.
Örnek
Şöyle yaparız.
myArr=(A B C); echo ${#myArr[0]}
İlk eleman olan A'nın uzunluğunu verir. Sonuç olarak 1 alırız.
Örnek
Elimizde şöyle bir dizi olsun.
array[0]="Shields at 90%"
array[1]="Engaging proton overdrive"
array[2]="Autopilot disengaged"
array[3]="Targetting solution available"
array[4]="Alert. Incoming missile."
array[5]="Deploying countermeasures."
array[6]="Firing torpedoes."
array[7]="Engaging auto-cannon."
array[8]="Severe damage on deck 17. Sealing off."
array[9]="Deploying repair droids to deck 17."

line=${array[$RANDOM % ${#array[@]}]}
speech "$line"
.bashrc dosyasına  şöyle yaparız. Böylece terminalden her komut çalıştırdığımızda farklı bir ses çıkarır.
PROMPT_COMMAND="bash $HOME/PATH/TO/myscript.sh"
String'in Uzunluğunu Bulma
Şöyle yaparız.
myvar="some string"; echo ${#myvar}
Sonuç olarak 11 alırız.

Tüm Diziyi Dolaşmak - "${arr[@]}" veya "${arr[*]}" Karakterleri
Array Expansion yazısına taşıdım

Diziden Çıkartma Yapmak
Şöyle yaparız. $# -1 ile en son elemana erişiriz.
local argv=( "$@" )
local last="${argv[$# - 1]}"
argv=( "${argv[@]:0:$# - 1}" )
Diziye Ekleme Yapmak
+=(...) şeklinde yapılır.

Örnek
Şöyle yaparız.
# this.txt first line is [Test this]
# another.txt first line is [Test another]
paths=(
  ./this/path/this.txt
  ./another/path/another.txt
)

for i in ${paths[@]}; do
  read -r line < $i
  lines+=("$line")
done

15 Haziran 2020 Pazartesi

Debian Nedir

Giriş
Debian iki farklı anlama geliyor.
1. Debian Linux sürümü var.
2. Bir de Debian tabanlı Linux sürümleri var. Örneğin Ubuntu,  Debian tabanlı bir Linux dağıtımıdır.

Çekirdek
Debian Sistemler iki farklı çekirdek kullanabilir. Açıklaması şöyle.
Debian systems currently use the Linux kernel or the FreeBSD kernel.
Ancak Farklı Linux Türevlerinin Kernel'ları Yer Değiştiremez. Buraya bakabilirsiniz.

Paketleme Sistemi
.deb uzantlı paketler kullanılır. Paketleri kurmak için apt komutu kullanılır. Açıklaması şöyle
Debian comes with over 51,000 packages (precompiled software that is bundled up in a nice format for easy installation on your machine), a package manager (APT), and other utilities that make it possible to manage thousands of packages on thousands of computers as easily as installing a single application.
Snap Paketleri
Ubuntu yavaş yavaş snap paketleme sistemine geçiyor. snap komutuna bakabilirsiniz

14 Haziran 2020 Pazar

dd komutu - Kullanmayın

Giriş
Bu komut "data definition" kelimelerinin kısalması olsa da ben "disk dump" olarak hatırlamayı daha kolay buluyorum.  Tehlikeli bir komut olduğu için bazıları şakayla karışık "disk destroyer" olarak ta anıyor.  Bir dosyadan başka dosyaya bloklar şeklinde veri aktarmaya yarar.

Tarihçesi
Açıklaması şöyle
The command dd was modeled after the command DDR (Disk Dump and Restore) from IBM mainframes from the 1960s and is mainly intended to convert and reblock block oriented I/O from/to block oriented disks.
dd Çıktısı
Şöyledir. Burada 8 s aslında "latency veya gecikme" diye nitelenebilir. 255 MB/s ise "speed veya hız"  diye nitelenebilir.
$ dd status=progress if=/dev/urandom of=/dev/null bs=100M count=20 iflag=fullblock
2097152000 bytes (2.1 GB, 2.0 GiB) copied, 8 s, 255 MB/s 

Neden Tehlikeli
bs + iflag = fullblock şeklinde kullanılması unutulduğu için tehlikeli.

bs seçeneği
Block size anlamına gelir. Okuma/yazma işleminde kullanılacak blokların büyüklüğünü belirtir. Blok büyüklüğü rakam veya okunabilir (1M) şekilde belirtilebilir.

Okuma yapılan kaynak belirtilen blok büyüklüğünde okumaya desteklemiyorsa daha küçük bir miktar okunabilir.

Örneğin /dev/urandom bir üst sınıra sahiptir ve 1M'lik bloklar şeklinde okunamaz!.

Örnek
Diski 0 ile doldurmak için şöyle yaparız.
dd if=/dev/zero of=/dev/sdb bs=1M
count seçeneği
Okuma/yazma işleminin kaç kere yapılacağını belirtir.

bs + conv seçeneği
bs seçeneği conv seçeneği ile birlitek kullanılabilir. Açıklaması şöyle. Yani bs seçeneğinin döndürdüğü blok büyüklüğü conv seçeneği tarafından değiştirilebilir.
If the bs= expr operand is specified and no conversions other than syncnoerror, or notrunc are requested, the data returned from each input block shall be written as a separate output block; if the read returns less than a full block and the sync conversion is not specified, the resulting output block shall be the same size as the input block. If the bs= expr operand is not specified, or a conversion other than syncnorerror, or notrunc is requested, the input shall be processed and collected into full-sized output blocks until the end of the input is reached.
conv seçeneği - ascii seçeneği
EBCDIC dosyayı ASCII dosyaya çevirmek için şöyle yaparız.
dd if=blah.ebcdic conv=ascii > blah.txt
conv seçeneği - notrunc
Çıktı dosyasını truncate edip etmemeyi bu seçenek ile belirtiriz. oflag ile kullanılırsa dosyanın sonuna ekleme yapılabilir.

Örnek
Dosyayı truncate etmeden seek ile dosyanın ortasından başlayarak bazı byte'lar yazarak dosyayı özellikle bozmak için şöyle yaparız.
dd if=/dev/zero of=file_to_fuzz.zip bs=1 count=1 seek=N conv=notrunc
conv seçeneği - sync - 0 İle Padler
Bu seçenek son derece tehlikeli. Eğer kısmı okuma varsa (partial read) block size'ı padleyerek doldurur. Açıklaması şöyle,
sync   pad  every  input  block  with  NULs to ibs-size; when used with
          block or unblock, pad with spaces rather than NULs
if seçeneği
input file anlamına gelir. Hangi dosyadan okunacağını belirtir.
dd if=/dev/zero of=10MBfile1 count=10000 bs=1024
bs + iflag seçeneği
bs seçeneği iflag seçeneği ile birlitek kullanılabilir.

iflag seçeneği - fullblock
Normalde eğer belirtilen blok büyüklüğünden daha az veri okunursa dd komutu uyarı mesajı verir. Görmek için şöyle yaparız.
$ dd status=progress if=/dev/urandom of=/dev/null bs=100M count=20 
dd: warning: partial read (33554431 bytes); suggest iflag=fullblock
Bunu düzeltmek için iflag=fullblock kullanarak şöyle yaparız.
$ dd status=progress if=/dev/urandom of=/dev/null bs=100M count=20 iflag=fullblock
2097152000 bytes (2.1 GB, 2.0 GiB) copied, 8 s, 255 MB/s 
of seçeneği
output file anlamına gelir. Hangi dosyaya yazılacağını belirtir.

oflag seçeneği
Örnek
Dosyanın sonuna ekleme yapmak için şöyle yaparız.
dd if=/dev/zero of=12mb.bin bs=1MiB count=10 conv=notrunc oflag=append
seek seçeneği
Başlangıçtan itibaren kaç byte sonra yazma işlemi olacağını belirtir.
$ dd if=tmp of=test obs=1 seek=1460 conv=notrunc
swab seçeneği
Açıklaması şöyle. İki byte'ın yerini değiştirir. Yani little endian'dan big endian'a çevirir.
swap every pair of input bytes

10 Haziran 2020 Çarşamba

sudo komutu

Giriş
sudo "substitude user do" veya "switch user do" olarak hatırlanabilir.

Güvenlik
sudo sürekli root kullanıcı olarak çalışmaktan alıkoyduğu için bir nevi güvenlik tedbiri gibi de düşünülebilir.  Açıklaması şöyle.
Usually, when you're on Linux, you're acting as a non-root user. A lot of things, like installing packages with apt, need root/sudo permission to be used. The sudo binary is there to give the normal user permissions to use root level actions like apt install.

You should not be using Linux all the time as root. This is because if you're compromised, the attacker would have root access to your system, which means they can do pretty much anything on your system. Instead, you run Linux as a non-root user, so that even if your account gets compromised, the attacker can't immediately get root access.
Sudo Nasıl Çalışır
1. sudo komutunu çalıştırınca aslında iki tane uygulama çalışıyor. İlki sudo, diğeri ise sudo'ya geçtiğimiz uygulama ismi. sudo root olarak başlar çünkü setuid kullanır. Açıklaması şöyle
/usr/bin/sudo is setuid root, so it automatically becomes root when you type sudo. If it weren't setuid root, it won't be able to switch to root.

But I suggest you don't set random commands setuid root. sudo was designed to use that way and it makes many security checks before actually let you run the command. By definition, if you type a command name in the terminal, you are running that command as your current user ID (unless the command elevates privileges by itself, eg. by being setuid root, or using sudo internally as in Tony's solution). sudo is there to clearly distinguish command being run as non-root from command being run as root. 
Örneğin şöyle yaparız.
sudo ./myapp -i aparam
2. sudo önce fork() çağrısı ile kendi kopyasını yaratıyor. Daha sonra sonra execve() ile belirttiğimiz uygulamayı çalıştırıyor. Ağaç olarak bakarsak şöyledir.
       ├─bash───sudo───myapp
  child of bash--^      ^--child of sudo
Ortam Değişkenleri
SUDO_ASKPASS
Örnek
Şöyle yaparız
sudo_response=$(SUDO_ASKPASS=/bin/false sudo -A whoami 2>&1 | wc -l)
if [ $sudo_response = 2 ]; then
    can_sudo=1
elif [ $sudo_response = 1 ]; then
    can_sudo=0
else
    echo "Unexpected sudo response: $sudo_response" >&2
    exit 1
fi

Redirection
Örnek
Elimizde şöyle bir kod olsun. Bu kod hata verir.
$ sudo echo "Include thing" >> /etc/httpd/conf.d/vhosts.conf
-bash: /etc/httpd/conf.d/vhosts.conf: Permission denied
Açıklaması şöyle.
Sudo elevates the process it calls, it does not elevate any of the current shell's processing like redirection, globbing, etc.

The file redirection >> /etc/httpd/conf.d/vhosts.conf is being processed by your current shell, which is still running under your current privileges.
Her şeyi tek tırnak içine alarak sorun çözülebilir. Şöyle yaparız.
sudo bash -c 'echo "Include thing" >> /etc/httpd/conf.d/vhosts.conf'
sudo ve su
sudo komutunun su komutundan daha güvenli olduğu söyleniyor.

sudoers dosyası
sudoers dosyası yazısına bakabilirsiniz.

-H seçeneği
Normalde bu seçeneği kullanmaya gerek yok. HOME ortam değişkenini hedef kullanıcının dizini yapar.
Örnek
Şöyle yaparız.
$ sudo printenv HOME  # Shows root's home, even without -H or -i.
/root
$ sudo -u as printenv HOME  # Shows as's home, even without -H or -i.
/home/as
$ sudo -H printenv HOME  # Also shows root's home.
/root
$ sudo -Hu as printenv HOME  # Also shows as's home.
/home/as
-i seçeneği
Açıklaması şöyle.
-i, --login
  Run the shell specified by the target user's password database entry as a login shell.
root olarak shell açabilmek için root'a atanmış bir shell olması gerekir. /etc/passwd dosyasında root için olan satır genelde şöyledir
root:x:0:0:root:/root:/bin/bash
Eğer root için shell atanmasaydı yani şöyle olsaydı bu seçenek işe yaramazdı
root:x:0:0:root:/root:/usr/sbin/nologin
-k seçeneği
Açıklaması şöyle. Tekrar şifre sorulmasını sağlar.
When used alone, the -k (kill) option to sudo invalidates the user's cached credentials. The next time sudo is run a password will be required. This option does not require a password and was added to allow a user to revoke sudo permissions from a .logout file. Not all security policies support credential caching.
        When used in conjunction with a command or an option that may require a password, the -k option will cause sudo to ignore the user's cached credentials. As a result, sudo will prompt for a password (if one is required by the security policy) and will not update the user's cached credentials.
-u seçeneği
Kullanıcı adını belirtir. Açıklaması şöyle. sudo sadece root olarak çalışmak zorunda değildir.
-u user, --user=user

Run the command as a user other than the default target user (usually root).
Örnek
Elimizde şöyle bir komut olsun. Bu komut yetki hatası veriyor.
sudo -u chris ls /root
ls: cannot open directory '/root': Permission denied
Açıklaması şöyle
sudo -u chris runs the given command as user chris, not as root with USER set to chris. So if chris can’t access /root, sudo -u chris won’t change that.
Örnek
Şöyle yaparız.
sudo -u user command
Örnek
$HOME ortam değişkeni belirtilen kullanıcı gibi olur. Şöyle yaparız.
$ sudo printenv HOME  # Shows root's home, even without -H or -i.
/root
$ sudo -u as printenv HOME  # Shows as's home, even without -H or -i.
/home/as

/etc/hosts dosyası - DNS kullanmadan Bazı İsimlerin IP Adresine Dönüştürülmesini Sağlar - localhost Satırı Burada Tanımlanır

Giriş
Bu yazıyla ilgili olarak hostnamectl komutu yazısına bakabilirsiniz.

etc/hosts Dosyası Ne İşe Yarar?
etc/hosts dosyası DNS kullanmadan bazı isimlerin IP adresine dönüştürülmesini sağlar. Bu dosya değiştirilince etkisi hemen görülebilir. Açıklaması şöyle.
Changes to /etc/hosts file seem to take effect immediately.
Satırın Formatı
Satırın şekli şöyledir
IP_address canonical_hostname [aliases...]
Önce IP adresi sonra isim gelir.

Örnek
Şöyle yaparız.
10.0.0.1 chassisOne
Örnek
Şöyle yaparız
10.0.0.1 facebook.com
10.0.0.2 google.com
localhost Satırı
localhost bir Doman Name'i temsil eder. IP adresi değildir
Örnek
localhost hem IPv4 hem de Ipv6 için olabilir. Şöyle yaparız
127.0.0.1    localhost
::1          localhost
Örnek
Benim sisteminde şöyle
127.0.0.1 localhost
127.0.1.1 acelya
Eğer localhost tanımlı değilse şu hatayı alırız.
Error resolving 'localhost': Name or service not known.
Örnek
Şöyle yaparız
127.0.0.1       localhost
127.0.1.1       yourhostname

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
Kendi Makinem İçin localhost Dışında Bir Satır Daha
Eğer localhost kelimesi dışında başka bir ismi daha 127.0.0.1 olarak çözmek istersek yeni bir satır daha eklerim. Şöyle yaparız.
127.0.0.1 thehostnametoresolvetolocalhost
dışarıya erişimi engellemek
Bazı sistemlerde şöyle satırlar var. Ancak bu yöntem çok iyi bir çözüm değil.
127.0.0.1 websiteiwanttoblock.com
127.0.0.1 anotherone.com
...
etc/hosts Dosyası  ve libc İlişkisi
Açıklaması şöyle
libc (in ways that differ in different operating systems) uses /etc/hosts to override hostname lookups. this can sometimes be useful when testing things but often i just forget stuff in there...
Bu dosyada bir şey unutulması artık DNS kullanılmadığı için eğer karşı sunucun adresi değişirse sıkıntı yaratabilir.

Örnek
GitHub sunucusunun adresini değişmesi. Açıklaması şöyle.
192.30.253.113 is a github address, since they own 192.30.252.0/22. you can run whois 192.30.253.113 to confirm. it's likely that that was a valid server address for github.com at some point, but was decommissioned at a few days ago. i can't even ping it. they'll have removed it from their dns servers, but since it's hardcoded in your laptop's /etc/hosts it's oblivious to that change!
getaddrinfo metodu
getaddrinfo metodu libc'nin bir parçasıdır. Açıklaması şöyle.
The getaddrinfo(3) function, which is the only standard name resolving interface will just open and read /etc/hosts each time it is called to resolve a hostname.
Örnek
Dosyanın hep okunduğunu görmek için şöyle yaparız.
strace -e trace=file wget -O /dev/null http://www.google.com http://www.facebook.com 
  http://unix.stackexchange.com 2>&1 | grep hosts
open("/etc/hosts", O_RDONLY|O_CLOEXEC)  = 4
open("/etc/hosts", O_RDONLY|O_CLOEXEC)  = 5
open("/etc/hosts", O_RDONLY|O_CLOEXEC)  = 4

8 Haziran 2020 Pazartesi

udev - /dev Dosya Sistemini Yönetir

Giriş
Açıklaması şöyle. Eskiden bu işi devfsd yapardı.
udev, a daemon that manages the contents of /dev in a temporary filesystem, or by devtmpfs, which is a lightweight replacement for devfs that is used in some minimal systems.
devfs ve Unix
Açıklaması şöyle.
But the devfs that used to exist in Linux was entirely Linux-specific. The ones that exist in XNU (macOS/iOS) and various BSDs are completely separate implementations; the only things they had in common were their names and their general purpose.
Eski Unix'te /dev dizini
Açıklaması şöyle
In 1986 (and for a few years after that still), /dev wasn’t handled by a special file system. It was generally a directory on the root file system, and its contents were largely static: a series of device nodes, created by mknod. Many systems had some way of creating the “standard” nodes, for example a Makefile in V7 or MAKEDEV.
/dev - dev Dosya Sistemi yazısına bakabilirsiniz