Disk dolana kadar neden "dd" ye "tar" boruları durmuyor?


18

Tek bir disk görüntüsünün katran arşivim var. Bu tar dosyasının içindeki görüntü yaklaşık 4GB boyutundadır. Disk görüntüsünü bir SD karta yazmak için tar xfiçine çıkış yapıyorum dd. Disk dolumu kart dolana kadar asla durmaz. İşte benim kabuk oturumu:

$ ls -l disk.img.tgz
-rw-r--r-- 1 confus confus 192M Okt  5 00:53

$ tar -tvf disk.img.tgz
-rw-r--r-- root/root 4294968320 2018-10-05 00:52 disk.img

$ lsblk -lb /dev/sdc
NAME MAJ:MIN RM        SIZE RO TYPE MOUNTPOINT
sdc    8:32   1 16022241280  0 disk

$ tar zxf disk.img.tgz -O | sudo dd status=progress conv=sync bs=1M of=/dev/sdc
[sudo] password for user: 
15992881152 bytes (16 GB, 15 GiB) copied, 212 s, 75,4 MB/s 
dd: error writing '/dev/sdc': No space left on device
0+15281 records in
15280+0 records out
16022241280 bytes (16 GB, 15 GiB) copied, 217,67 s, 73,6 MB/s

Neden? İsabet 4GB görüntüsünü 16GB sepetine yazdıktan sonra durmalı ve asla alanınız kalmadı!


Bunu çalıştırmayı ddve başka bir dosyaya yazmayı denemek için disk alanınız var mı? tar zxf disk.img.tgz -O | dd status=progress conv=sync bs=1M of=/path/to/some/file/on/disk? Öyleyse, bu size orijinal dosyanın tam bir kopyasını verir mi?
Andy Dalton

2
Neden var conv=sync? conv=fsyncBelki de kullanmak istediniz mi?
Ralph Rönnquist

Dosyanın gerçek boyutundan emin misiniz? Gzip'in dosya boyutlarını depolamak için sadece 32 biti olduğunu biliyorum, bu yüzden 4GB'ın üzerindeki dosyaların boyutunu yanlış alıyor. Katranın benzer bir sınırlamaya sahip olup olmadığından emin değilim.
David Conrad

Yanıtlar:


50

Çünkü yanlış yapıyorsun.

Kullandığınız bs=1Mdaha küçük okur olacak, ancak Stdin, kanal okunurken. Aslında, dd'ye göre, tek bir tam okuma almadınız.

Ve sonra conv=synctamamlanmamış okumaları sıfırlarla tamamlar.

0+15281 records in
15280+0 records out

dd0 tam ve 15281 tamamlanmamış okuma aldı ve 15280 tam blok yazdı (dönş. = senkronize sıfır dolu). Böylece, boş alan kalmayıncaya kadar çıktı girişten çok daha büyüktür.

   sync   pad  every  input  block  with  NULs to ibs-size; when used with
          block or unblock, pad with spaces rather than NULs

Bunu çözmek için kaldırabilir conv=syncve ekleyebilirsiniz iflag=fullblock.


Örneklemek gerekirse yes, hangisinin varsayılan olarak sonsuz "y \ ny \ ny \ n" olduğunu söyler.

$ yes
y
y
y
^C
$ yes | hexdump -C
00000000  79 0a 79 0a 79 0a 79 0a  79 0a 79 0a 79 0a 79 0a  |y.y.y.y.y.y.y.y.|
*

İle dd bs=1M conv=syncböyle görünüyor:

$ yes | dd bs=1M conv=sync | hexdump -C
00000000  79 0a 79 0a 79 0a 79 0a  79 0a 79 0a 79 0a 79 0a  |y.y.y.y.y.y.y.y.|
*
0001e000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00100000  79 0a 79 0a 79 0a 79 0a  79 0a 79 0a 79 0a 79 0a  |y.y.y.y.y.y.y.y.|
*
00112000  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*

Böylece "y \ ny \ ny \ n" (0x00000 - 0x1e000, 122880 Byte) tamamlanmamış bir blok alır ve ardından kalan 1M'yi sıfır olarak yazar (0x01e000 - 0x100000, 925696 Bayt). Çoğu durumda, bunun olmasını istemezsiniz. Her okumanın ne kadar eksik olduğu konusunda gerçek bir kontrole sahip olmadığınız için sonuç yine de rastgele. Burada ikinci okuma artık 122880 Bayt değil, 73728 Bayt.

dd conv=syncnadiren kullanışlıdır ve hoş karşılanacağı durumlarda bile, okuma hataları aldığınızda sıfır yazmak gibi, işler onunla korkunç bir şekilde yanlış gidecektir.


Bu durumda, (Linux varsayarak) ddaltındaki komutu çalıştırmak, straceborudan her kısa okunmanın ardından 1 MB'lık tam bir yazma izlediğini gösterirdi.
Andrew Henle

2
@AndrewHenle bunun için sıkıntıya bile ihtiyaç duymaz, sadece çıktıya bakmak yeterlidir. Bir örnek eklendi
frostschutz

Bu aynı zamanda ddkomutun neden temelde kırılmış ve kullanılamaz olduğunu da gösterir . Bireysel reads ve writes'de çalışacağı belirtilir , ancak bu işlemler her zaman kısa okuma veya yazma üretebilecekleri şekilde belirtilir ve bu bir hata değildir. Sonuç olarak, davranışı ddbelirtilmemiş davranışa bağlıdır.
R ..

Çok eğitici cevap için teşekkürler. Başka birinin önerdiği gibi, ben bir eşek olduğumu ve birçok seçeneği karıştırdım dd, ama bu senden bir şey öğrenmeme neden oldu. Hala tam olarak emin olmadığım şey, ne zaman ve ne zaman ddsona ereceğidir. Sanırım olurdu, ama aslında 1 kısım gerçek veri ve 9 kısım sıfır yazdığı için, yaklaşık 40G yazdıktan sonra dururdu. Bu doğru mu?
con-f-use

@R .., bu özellik, okuma ve yazmaların blok boyutunu önemseyen aygıt sürücülerinde çok kullanışlıdır. Bunu önemseyen bazı teyp sürücüleri kullandığımı hatırlıyorum. Bu durumda, tabii ki gerekli değil, sadece doğrudan diske yönlendirebilir (gerçi canlı bir ilerleme raporu
almıyorum
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.