¿Por qué no se detiene el comando de cadenas?


30

El stringscomando se comporta de manera extraña, aparentemente no deja de escribir en un archivo incluso si la unidad se queda sin espacio. ¿O tal vez me estoy perdiendo algo?

Ejecuto lo siguiente:

# strings /dev/urandom > random.txt

Esto seguía funcionando y no se detenía incluso después de llenar el disco (un flash usb normal).

luego, para ser más rápido, creé un ramdisk e intenté nuevamente el mismo comando. Tampoco se detuvo.

Entiendo que urandomno es un archivo normal y que stringsla salida también se redirige, sin embargo, en los dos casos anteriores, el catcomando informó el error cuando no había más espacio.

# cat /dev/urandom > random.txt
cat: write error: No space left on device
  1. ¿Es este el comportamiento normal de las cuerdas? Si es así, ¿por qué?
  2. ¿Dónde se escriben los datos después de que no queda más espacio?

1
¿Cuál fue la indicación de que su primer comando realmente había llenado el disco?
Kusalananda

1
@Kusalananda Fue informado por df. Lo estaba monitoreando desde otra terminal virtual usando watch df -h
user174174

2
@Kusalananda: puedes probar esto fácilmente constrace strings /dev/urandom > /dev/full
Peter Cordes

2
@mosvy OpenBSD usa esa misma stringsimplementación de GNU binutils. Me refería al stracecomando.
Kusalananda

2
@Kusalananda bien, debido a que la "cadena de herramientas BSD" sustitución de cadenas (1) no comprueba el valor de retorno de putchar () o bien
mosvy

Respuestas:


63

Si GNU catno puede escribir lo que lee, saldrá con un error :

/* 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"));
}

A GNU strings, por otro lado, no le importa si logró escribir con éxito:

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

Por lo tanto, todas esas escrituras fallan, pero stringscontinúan alegremente, hasta que llega al final de la entrada, que nunca será.

$ 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)
...

19
Buen análisis Yo diría que debería considerarse un error en strings.
Kasperd

3
¿Alguien planea reportar el error?
Nate Eldredge
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.