Pádraig Brady wrote:
There were some issues noted with that,
but IMHO they were lesser than the current issue.
No matter which format we pick, fans of the other format will complain. Instead,
let's output the information in both formats. I did that with the attached patch.
We will have to be careful to not corrupt output
when switching with status=progress (due to possibly shorter status line).
I didn't know about this problem. Could you explain it?
Ah. Is this due to glitches when the size grows from (say) "1023 KiB" to "1.0
MiB", or is it something else?
>From 9d4e79f5c2d23544f989e73a8b37a3d8908f3b4a Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email protected]>
Date: Thu, 31 Dec 2015 11:43:09 -0800
Subject: [PATCH] dd: summarize in --human-readable format too
Problem reported by Linda Walsh in: http://bugs.gnu.org/17505
* NEWS: Document this.
* doc/coreutils.texi (dd invocation): Use a simpler script.
Adjust output example to match new behavior.
* src/dd.c (human_size): Remove.
All uses changed to use human_readable and ...
(human_opts): ... this new constant.
(abbreviation_lacks_prefix): New function.
(print_xfer_stats): Use it. Output both --si and --human-readable
summaries, but only if they have prefixes.
* tests/dd/reblock.sh, tests/dd/stats.sh: Test new behavior.
---
NEWS | 4 +++
doc/coreutils.texi | 22 ++++++++---------
src/dd.c | 70 ++++++++++++++++++++++++++++++++---------------------
tests/dd/reblock.sh | 4 +--
tests/dd/stats.sh | 6 ++---
5 files changed, 63 insertions(+), 43 deletions(-)
diff --git a/NEWS b/NEWS
index 5080f0f..ae8d9e0 100644
--- a/NEWS
+++ b/NEWS
@@ -29,6 +29,10 @@ GNU coreutils NEWS -*- outline -*-
** New features
+ dd now summarizes sizes in --human-readable format too, not just --si.
+ E.g., "3441325000 bytes (3.4 GB, 3.2 GiB) copied". It omits the summaries
+ if they would not provide useful information, e.g., "3 bytes copied".
+
md5sum now supports the --ignore-missing option to allow
verifying a subset of files given a larger list of checksums.
This also affects sha1sum, sha224sum, sha256sum, sha384sum and sha512sum.
diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index 64419c7..8eb2a3e 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -8835,23 +8835,23 @@ trap '' USR1
# which can be triggered by reception of signals.
dd iflag=fullblock if=/dev/zero of=/dev/null count=5000000 bs=1000 & pid=$!
-# Output stats every half second
-until ! kill -s USR1 $pid 2>/dev/null; do sleep .5; done
+# Output stats every second.
+while kill -s USR1 $pid 2>/dev/null; do sleep 1; done
@end example
-The above script will output in the following format
+The above script will output in the following format:
@example
-859+0 records in
-859+0 records out
-4295000000 bytes (4.3 GB) copied, 0.539934 s, 8.0 GB/s
-1000+0 records in
-1000+0 records out
-5000000000 bytes (5.0 GB) copied, 0.630785 s, 7.9 GB/s
+3441325+0 records in
+3441325+0 records out
+3441325000 bytes (3.4 GB, 3.2 GiB) copied, 1.00036 s, 3.4 GB/s
+5000000+0 records in
+5000000+0 records out
+5000000000 bytes (5.0 GB, 4.7 GiB) copied, 1.44433 s, 3.5 GB/s
@end example
-Note also the @samp{status=progress} option which periodically updates
-the last line of the transfer statistics above.
+The @samp{status=progress} option periodically updates the last line
+of the transfer statistics above.
@vindex POSIXLY_CORRECT
On systems lacking the @samp{INFO} signal @command{dd} responds to the
diff --git a/src/dd.c b/src/dd.c
index a5557a8..4a24775 100644
--- a/src/dd.c
+++ b/src/dd.c
@@ -673,15 +673,10 @@ Options are:\n\
exit (status);
}
-static char *
-human_size (size_t n)
-{
- static char hbuf[LONGEST_HUMAN_READABLE + 1];
- int human_opts =
- (human_autoscale | human_round_to_nearest | human_base_1024
- | human_space_before_unit | human_SI | human_B);
- return human_readable (n, hbuf, human_opts, 1, 1);
-}
+/* Common options to use when displaying sizes and rates. */
+
+enum { human_opts = (human_autoscale | human_round_to_nearest
+ | human_space_before_unit | human_SI | human_B) };
/* Ensure input buffer IBUF is allocated. */
@@ -693,9 +688,15 @@ alloc_ibuf (void)
char *real_buf = malloc (input_blocksize + INPUT_BLOCK_SLOP);
if (!real_buf)
- error (EXIT_FAILURE, 0,
- _("memory exhausted by input buffer of size %"PRIuMAX" bytes (%s)"),
- (uintmax_t) input_blocksize, human_size (input_blocksize));
+ {
+ uintmax_t ibs = input_blocksize;
+ char hbuf[LONGEST_HUMAN_READABLE + 1];
+ error (EXIT_FAILURE, 0,
+ _("memory exhausted by input buffer of size %"PRIuMAX" bytes (%s)"),
+ ibs,
+ human_readable (input_blocksize, hbuf,
+ human_opts | human_base_1024, 1, 1));
+ }
real_buf += SWAB_ALIGN_OFFSET; /* allow space for swab */
@@ -715,10 +716,16 @@ alloc_obuf (void)
/* Page-align the output buffer, too. */
char *real_obuf = malloc (output_blocksize + OUTPUT_BLOCK_SLOP);
if (!real_obuf)
- error (EXIT_FAILURE, 0,
- _("memory exhausted by output buffer of size %"PRIuMAX
- " bytes (%s)"),
- (uintmax_t) output_blocksize, human_size (output_blocksize));
+ {
+ uintmax_t obs = output_blocksize;
+ char hbuf[LONGEST_HUMAN_READABLE + 1];
+ error (EXIT_FAILURE, 0,
+ _("memory exhausted by output buffer of size %"PRIuMAX
+ " bytes (%s)"),
+ obs,
+ human_readable (output_blocksize, hbuf,
+ human_opts | human_base_1024, 1, 1));
+ }
obuf = ptr_align (real_obuf, page_size);
}
else
@@ -746,17 +753,23 @@ multiple_bits_set (int i)
return MULTIPLE_BITS_SET (i);
}
+static bool
+abbreviation_lacks_prefix (char const *message)
+{
+ return message[strlen (message) - 2] == ' ';
+}
+
/* Print transfer statistics. */
static void
-print_xfer_stats (xtime_t progress_time) {
- char hbuf[LONGEST_HUMAN_READABLE + 1];
- int human_opts =
- (human_autoscale | human_round_to_nearest
- | human_space_before_unit | human_SI | human_B);
+print_xfer_stats (xtime_t progress_time)
+{
+ char hbuf[2][LONGEST_HUMAN_READABLE + 1];
double delta_s;
char const *bytes_per_second;
-
+ char const *si = human_readable (w_bytes, hbuf[0], human_opts, 1, 1);
+ char const *iec = human_readable (w_bytes, hbuf[1],
+ human_opts | human_base_1024, 1, 1);
if (progress_time)
fputc ('\r', stderr);
@@ -764,11 +777,14 @@ print_xfer_stats (xtime_t progress_time) {
since that makes it easy to use SI abbreviations. */
fprintf (stderr,
- ngettext ("%"PRIuMAX" byte (%s) copied",
- "%"PRIuMAX" bytes (%s) copied",
+ ngettext ("%"PRIuMAX" byte copied",
+ (abbreviation_lacks_prefix (si)
+ ? "%"PRIuMAX" bytes copied"
+ : abbreviation_lacks_prefix (iec)
+ ? "%"PRIuMAX" bytes (%s) copied"
+ : "%"PRIuMAX" bytes (%s, %s) copied"),
select_plural (w_bytes)),
- w_bytes,
- human_readable (w_bytes, hbuf, human_opts, 1, 1));
+ w_bytes, si, iec);
xtime_t now = progress_time ? progress_time : gethrxtime ();
@@ -778,7 +794,7 @@ print_xfer_stats (xtime_t progress_time) {
uintmax_t delta_xtime = now;
delta_xtime -= start_time;
delta_s = delta_xtime / XTIME_PRECISIONe0;
- bytes_per_second = human_readable (w_bytes, hbuf, human_opts,
+ bytes_per_second = human_readable (w_bytes, hbuf[0], human_opts,
XTIME_PRECISION, delta_xtime);
}
else
diff --git a/tests/dd/reblock.sh b/tests/dd/reblock.sh
index cd9d942..d950b39 100755
--- a/tests/dd/reblock.sh
+++ b/tests/dd/reblock.sh
@@ -23,14 +23,14 @@ print_ver_ dd
cat <<\EOF > exp-reblock || framework_failure_
0+2 records in
1+1 records out
-4 bytes (4 B) copied
+4 bytes copied
EOF
# 2 short reads -> 2 partial writes
cat <<\EOF > exp-no-reblock || framework_failure_
0+2 records in
0+2 records out
-4 bytes (4 B) copied
+4 bytes copied
EOF
diff --git a/tests/dd/stats.sh b/tests/dd/stats.sh
index da2c2d2..f2cbef9 100755
--- a/tests/dd/stats.sh
+++ b/tests/dd/stats.sh
@@ -60,14 +60,14 @@ for open in '' '1'; do
wait
# Ensure all data processed and at least last status written
- grep '250000000 bytes .* copied' err || { cat err; fail=1; }
+ grep '250000000 bytes (250 MB, 238 MiB) copied' err || { cat err; fail=1; }
done
progress_output()
{
{ sleep "$1"; echo 1; } | dd bs=1 status=progress of=/dev/null 2>err
- # Progress output should be for "byte ... copied", while final is "bytes ..."
- grep 'byte .* copied' err
+ # Progress output should be for "byte copied", while final is "bytes ..."
+ grep 'byte copied' err
}
retry_delay_ progress_output 1 4 || { cat err; fail=1; }
--
2.5.0