Mengapa perintah string tidak berhenti?

30

The stringsberperilaku perintah ganjil, tampaknya itu tidak berhenti menulis ke file bahkan jika drive kehabisan ruang. Atau mungkin saya melewatkan sesuatu?

Saya menjalankan yang berikut ini:

# strings /dev/urandom > random.txt

ini terus berjalan dan tidak berhenti bahkan setelah mengisi disk (usb flash biasa).

kemudian agar lebih cepat saya membuat ramdisk dan mencoba lagi perintah yang sama. itu juga tidak berhenti.

Saya mengerti bahwa urandomini bukan file biasa dan juga stringsoutput diarahkan, namun dalam kedua kasus di atas, catperintah melaporkan kesalahan ketika tidak ada lagi ruang.

# cat /dev/urandom > random.txt
cat: write error: No space left on device
  1. Apakah ini perilaku normal? Jika demikian, mengapa?
  2. Di mana data ditulis setelah tidak ada lagi ruang yang tersisa?
pengguna174174
sumber
1
Apa indikasi bahwa perintah pertama Anda telah mengisi disk?
Kusalananda
1
@ Kusalananda Dilaporkan oleh df. Saya sedang memonitornya dari terminal virtual lain menggunakan watch df -h
user174174
2
@ Kusalananda: Anda dapat menguji ini dengan mudah denganstrace strings /dev/urandom > /dev/full
Peter Cordes
2
@mosvy OpenBSD menggunakan stringsimplementasi yang sama dari binutils GNU. Saya mengacu pada straceperintah.
Kusalananda
2
@Kusalananda OK, karena "BSD toolchain" penggantian string (1) tidak memeriksa nilai kembali dari putchar () baik
mosvy

Jawaban:

63

Jika GNU cattidak dapat menulis apa yang dibaca, GNU akan keluar dengan kesalahan :

/* Write this block out.  */

{
  /* The following is ok, since we know that 0 < n_read.  */
  size_t n = n_read;
  if (full_write (STDOUT_FILENO, buf, n) != n)
    die (EXIT_FAILURE, errno, _("write error"));
}

GNU strings, di sisi lain, tidak peduli apakah itu berhasil menulis berhasil:

while (1)
  {
    c = get_char (stream, &address, &magiccount, &magic);
    if (c == EOF)
      break;
    if (! STRING_ISGRAPHIC (c))
      {
        unget_part_char (c, &address, &magiccount, &magic);
        break;
      }
    putchar (c);
  }

Jadi semua penulisan itu gagal, tetapi stringsterus berlanjut dengan riang, hingga mencapai akhir input, yang tidak akan pernah ada.

$ strace -e write strings /dev/urandom > foo/bar
write(1, "7[\\Z\n]juKw\nl [1\nTc9g\n0&}x(x\n/y^7"..., 4096) = 4096
write(1, "\nXaki%\ndHB0\n?5:Q\n6bX-\np!E[\n'&=7\n"..., 4096) = 4096
write(1, "%M6s\n=4C.%\n&7)n\nQ_%J\ncT+\";\nK*<%\n"..., 4096) = 4096
write(1, "&d<\nj~g0\nm]=o\na=^0\n%s]2W\nM7C%\nUK"..., 4096) = -1 ENOSPC (No space left on device)
write(1, "~\nd3qQ\n^^u1#\na#5\\\n^=\t\"b\n*91_\n ]o"..., 4096) = -1 ENOSPC (No space left on device)
write(1, "L\n6QO1x\na,yE\nk>\",@Z\nyM.ur\n~z\tF\nr"..., 4096) = -1 ENOSPC (No space left on device)
write(1, "\n61]R\nyg9C\nfLVu\n<Ez:\n.tV-c\nw_'>e"..., 4096) = -1 ENOSPC (No space left on device)
write(1, "\nCj)a\nT]X:uA\n_KH\"B\nRfQ4G\n3re\t\n&s"..., 4096) = -1 ENOSPC (No space left on device)
write(1, "j\nk7@%\n9E?^N\nJ#8V\n*]i,\nXDxh?\nr_1"..., 4096) = -1 ENOSPC (No space left on device)
write(1, "ia\tI\nQ)Zw\nnV0J\nE3-W \n@0-N2v\nK{15"..., 4096) = -1 ENOSPC (No space left on device)
write(1, "\nZ~*g\n)FQn\nUY:G\ndRbN\nn..F\nvF{,\n+"..., 4096) = -1 ENOSPC (No space left on device)
...
Olorin
sumber
19
Analisis yang bagus. Saya akan mengatakan itu harus dianggap sebagai bug di strings.
kasperd
3
Adakah yang berencana melaporkan bug tersebut?
Nate Eldredge