12.02.2018

dd komutu, bs, count, skip ve seek kullanımı

Zamana zaman kullandığım dd komutunun parametereleri ile ilgili güzel bir örnek olacağını düşündüğüm aşağıdaki örneği kolay hatırlamak için kullanmak istiyorum.

dd komutu, bir giriş dosyasından (karakter bazlı bir cihaz da olabilir) verileri alıp başka bir dosyaya (karakter bazlı başkak bir cihaz da olabilir) yazmaya yarar. Aslında çok faydalı bir araç. Örnek olarak giriş dosyamız input.txt'nin 0'dan 9'a ve a'dan z'ye devam eden aşağıdaki gibi düz bir metin içerği olsun:

0123456789abcdefghijklmnopqrstuvwxyz

Bu dosyayı dd komutu ile aşağıdaki şekilde kopyalayabiliriz:
dd if=input.txt of=output.txt
Bu komutun ardından output.txt de aynen yukarıdaki gibi bir içeriğe sahip olacaktır. dd, giriş dosyasından her seferinde varsayılan olarak 512 byte okuyarak çıkış dosyasına yazar. Bu işlemi giriş dosyasının sonu gelene kadar yapar. Bizim dosyamız 512 byte'tan küçük olduğu için bu işlemi bir adımda bitirdi. bs parametresiyle bu varsayılan blok boyutunu değiştirebiliriz. Hatta count parametresiyle toplamda kaç blok kopyalayacağını da belirtebiliriz. Örneğin sadece baştan 15 karakteri alabilmek için bs=1 ve count=15 ile bu komutu tekrarlayalım.
dd if=input of=output bs=1 count=15
Bunun sonucunda output.txt şöyle olur:

0123456789abcde

Tam olarak 15 karakter. Her komut çalıştırmamızda da şöyle bir çıkış üretir:

15+0 records in
15+0 records out
15 bytes copied, 0,0000456 s, 45,8 kB/s

Giriş dosyasından 15 karater alıp çıkış dosyasına 15 karakter yazdığını ve işlem sürelerini vermiş.

İşler skip ve seek parametreleri girince daha eğlenceli hale geliyor. Eğer giriş dosyasındaki rakamları atlayıp doğrudan harfleri çıkışa yazmak isteseydik (yani girişten 10 karakter, ya da bs, atlamak isteseydik) şöyle yapmamız gerekirdi:

dd if=input.txt of=output.txt bs=1 skip=10
Bu komutun sonunda output.txt dosyamız şöyle olur:

abcdefghijklmnopqrstuvwxyz

Dahası var. Eğer rakamları da bu alfabenin sonuna yazmak istiyorsak bu sefer giriş dosyasından 10 karakter okuyup, bu sefer de çıkış dosyasındaki ilk 26 karakteri atlayıp daha sonra yazmasını söylememiz gerekirdi. Bunu da seek parametresiyle yapmamaız gerekir.
dd if=input.txt of=output.txt bs=1 count=10 seek=26
Bu noktaya kadar output.txt dosyasının hep üzerine yazmıştık. Ama seek parametresini kullanmaya başlayınca durum değişecek. Belirtilen sayıda (10) karaktere dokunulmayıp, o sayıdan sonrasının (11) üzerine yazılmaya başlanacak. Bu komutun sonunda da çıkış dosyamız aynen şöyle olur:

abcdefghijklmnopqrstuvwxyz0123456789

Burada count=10 giriş dosyasından sadece rakamların okunmasını sağladı.

Bir başka güzel özelliği de girişten okuyup çıkışa yazmadan önce dönüştürme yapıyor olması. Örneğin girişteki karakterlerin hepsini büyük harfe çevirmesini istiyorsak conv=ucase parametresini kullanabiliriz.
dd if=input.txt of=output.txt conv=ucase
Benzer şekilde küçük harfe çevirmek için de lcase kullanılabilir.

Bazı durumlarda da giriş dosyasındaki her iki byte çiftinin yerlerini değiştirmek gerekir. Bu durumda conv=swab kullanılmalı:
dd if=input.txt of=output.txt bs=2 conv=swab
Çıkış şöyle olur:

1032547698badcfehgjilknmporqtsvuxwzy

Kullanım alanları bununla kısıtlı değil. Örnek olarak bir disk bölümünün yedeğini almak için:
# dd if=/dev/sda1 of=/home/username/part1_backup.img

Gerektiği anda da bu yedeği kullanarak disk bölümünü tekrar oluşturmak için
# dd if=/home/username/part1_backupimg of=/dev/sda1
Bu dosya elbette çok fazla yer kaplayabilir. Yedek alırken bir de gzip ile sıkıştırmak için:
# dd if=/dev/sda1 | gzip > /home/username/part1_backup.gz
ya da bzip ile sıkıştırmak için
# dd if=/dev/sda1 | bzip2 --best > /home/username/part1_backup.bz2

Bu sıkıştırılmış dosyayı kullanarak disk bölümünü tekrar oluşturmak için ise
# gunzip -c /home/username/part1_backup.gz | dd of=/dev/sda1
Uzun işlemlerde sürecin neresindeyiz, işlemin kaçta kaçı bitti, görmek istersek status=progress anahtarını kullanabiliriz.

Büyük disklerle çalışırken bs=64K kullanılması önerilmiş.  conv=noerror,sync gibi seçeneklerle hatlar olsa bile devam etmesi ve eşzamanlı giriş/çıkış (syncronized I/O) kullanılabileceği de belirtilmiş.

Daha başka özellikler için bakınız man dd.

Hiç yorum yok: