Tại sao lệnh dừng chuỗi không?


30

Các stringscư xử lệnh thật là thú vị, dường như nó không chỉ dừng lại bằng văn bản cho một tập tin ngay cả khi ổ chạy ra khỏi không gian. Hoặc có lẽ tôi đang thiếu một cái gì đó?

Tôi chạy như sau:

# strings /dev/urandom > random.txt

việc này vẫn tiếp tục chạy và không dừng lại ngay cả sau khi lấp đầy đĩa (đèn flash USB thông thường).

sau đó để nhanh hơn tôi đã tạo một ramdisk và thử lại lệnh tương tự. nó cũng không dừng lại.

Tôi hiểu rằng đó urandomkhông phải là một tệp thông thường và stringsđầu ra của nó cũng được chuyển hướng, tuy nhiên trong cả hai trường hợp trên, catlệnh đã báo cáo lỗi khi không còn dung lượng.

# cat /dev/urandom > random.txt
cat: write error: No space left on device
  1. Đây có phải là hành vi bình thường của chuỗi? Nếu vậy, tại sao?
  2. Dữ liệu được ghi ở đâu sau khi không còn chỗ trống?

1
Dấu hiệu cho thấy lệnh đầu tiên của bạn đã thực sự lấp đầy đĩa là gì?
Kusalananda

1
@Kusalananda Nó đã được báo cáo bởi df. Tôi đã theo dõi nó từ một thiết bị đầu cuối ảo khác bằng cách sử dụng watch df -h
user174174

2
@Kusalananda: bạn có thể kiểm tra điều này một cách dễ dàng vớistrace strings /dev/urandom > /dev/full
Peter Cordes

2
@mosvy OpenBSD sử dụng cùng một stringstriển khai từ GNU binutils. Tôi đã đề cập đến stracelệnh.
Kusalananda

2
@Kusalananda OK, bởi vì "BSD toolchain" thay thế các chuỗi (1) không kiểm tra giá trị trả về của putchar () hoặc
mosvy

Câu trả lời:


63

Nếu GNU catkhông thể viết ra những gì nó đọc, nó sẽ thoát với một lỗi :

/* 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, mặt khác, không quan tâm liệu nó có thể viết thành công hay không:

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

Vì vậy, tất cả những người viết đều thất bại, nhưng stringsvẫn tiếp tục vui vẻ, cho đến khi nó kết thúc đầu vào, điều này sẽ không bao giờ.

$ 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
Phân tích tốt đẹp. Tôi muốn nói rằng nên được coi là một lỗi trong strings.
kasperd

3
Bất cứ ai có kế hoạch báo cáo lỗi?
Nate Eldredge
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.