30

The strings command behaves weirdly, apparently it doesn't stop writing to a file even if drive run out of space. Or perhaps I'm missing something?

I run the following:

# strings /dev/urandom > random.txt

this was keep running and didn't stop even after filling the disk (a regular usb flash).

then to be quicker I created a ramdisk and tried again the same command. it also didn't stop.

I understand that urandom isn't a regular file and also strings's output is redirected, however in both cases above, the cat command reported the error when there was no more space.

# cat /dev/urandom > random.txt
cat: write error: No space left on device
  1. Is this normal behavior of strings? If so, why?
  2. Where is the data written after there's no more space left?
8
  • 1
    What was the indication that your first command had actually filled up the disk?
    – Kusalananda
    Commented Mar 6, 2019 at 7:33
  • 1
    @Kusalananda It was reported by df. I was monitoring it from another virtual terminal using watch df -h
    – user174174
    Commented Mar 6, 2019 at 7:40
  • 2
    @Kusalananda: you can test this easily with strace strings /dev/urandom > /dev/full Commented Mar 6, 2019 at 9:39
  • 2
    @mosvy OpenBSD uses that same strings implementation from GNU binutils. I was referring to the strace command.
    – Kusalananda
    Commented Mar 6, 2019 at 19:48
  • 2
    @Kusalananda OK, because the "BSD toolchain" replacement of strings(1) doesn't check for the return value of putchar() either
    – user313992
    Commented Mar 6, 2019 at 20:15

1 Answer 1

62

If GNU cat can't write out what it read, it will exit with an 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"));
}

GNU strings, on the other hand, doesn't care whether it managed to write successfully:

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

So all those writes fail, but strings continues merrily along, until it reaches end of input, which will be never.

$ 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)
...
2
  • 19
    Nice analysis. I'd say that should be considered a bug in strings.
    – kasperd
    Commented Mar 6, 2019 at 15:01
  • 3
    Anyone planning to report the bug? Commented Mar 7, 2019 at 16:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .