Pourquoi la commande strings ne s'arrête-t-elle pas?

30

La stringscommande se comporte bizarrement, apparemment, elle n'arrête pas d'écrire dans un fichier même si le lecteur manque d'espace. Ou peut-être que je manque quelque chose?

Je lance ce qui suit:

# strings /dev/urandom > random.txt

cela a continué à fonctionner et ne s'est pas arrêté même après avoir rempli le disque (un flash usb normal).

puis pour être plus rapide, j'ai créé un disque virtuel et réessayé la même commande. cela ne s'est pas arrêté non plus.

Je comprends que ce urandomn'est pas un fichier normal et que stringsla sortie de est également redirigée, mais dans les deux cas ci-dessus, la catcommande a signalé l'erreur lorsqu'il n'y avait plus d'espace.

# cat /dev/urandom > random.txt
cat: write error: No space left on device
  1. Est-ce le comportement normal des chaînes? Si oui, pourquoi?
  2. Où sont écrites les données après qu'il ne reste plus d'espace?
user174174
la source
1
Quelle était l'indication que votre première commande avait effectivement rempli le disque?
Kusalananda
1
@Kusalananda Il a été rapporté par df. Je le surveillais depuis un autre terminal virtuel en utilisant watch df -h
user174174
2
@Kusalananda: vous pouvez le tester facilement avecstrace strings /dev/urandom > /dev/full
Peter Cordes
2
@mosvy OpenBSD utilise la même stringsimplémentation de GNU binutils. Je parlais de la stracecommande.
Kusalananda
2
@Kusalananda OK, parce que le « BSD toolchain » remplacement des chaînes (1) ne vérifie pas la valeur de retour de putchar () soit
mosvy

Réponses:

63

Si GNU catne peut pas écrire ce qu'il a lu, il se fermera avec une erreur :

/* 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, d'autre part, ne se soucie pas s'il a réussi à écrire avec succès:

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);
  }

Donc toutes ces écritures échouent, mais se stringspoursuivent joyeusement, jusqu'à ce qu'elles atteignent la fin de l'entrée, ce qui ne sera jamais.

$ 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
la source
19
Belle analyse. Je dirais que cela devrait être considéré comme un bug strings.
kasperd
3
Quelqu'un prévoit-il de signaler le bogue?
Nate Eldredge