简体   繁体   中英

dd utility outputs different lines under the same command for sh and bash, how to force output of the last line inside the docker container?

Inside the docker container I test the

dd if=/dev/zero of=/tmp/test2.img bs=512 count=1000 2> >( grep copied )

line execution. I drill into container using 2 ways.

1) the classical one is docker exec -it 2b65c84ddce2 /bin/sh

the execution the line inside the contained inherinted from the alpine I'm greeting /bin/sh: syntax error: unexpected redirection beacuse of something near >(

2) when I enter the container into the bash executor like docker exec -it 2b65c84ddce2 /bin/bash

dd if=/dev/zero of=/tmp/test2.img bs=512 count=1000 2> >( grep copied ) returns no output dd if=/dev/zero of=/tmp/test2.img bs=512 count=1000 returns 2 lines output only, while the expectation is 3:

1+0 records in
1+0 records out

At the host level the same dd command is returning 3 lines like this:

dd if=/dev/zero of=/tmp/test2.img bs=512 count=1000
1000+0 records in
1000+0 records out
512000 bytes (512 kB, 500 KiB) copied, 0.0109968 s, 46.6 MB/s

and with redirection the output is the last line:

dd if=/dev/zero of=/tmp/test2.img bs=512 count=1000 2> >( grep copied )
512000 bytes (512 kB, 500 KiB) copied, 0.0076261 s, 67.1 MB/s

So how can I get the last line of dd output from the inside of the docker container?

PS.

The redirecting stderr to stdout doesn't help in general:

/ # dd if=/dev/zero of=/tmp/test2.img bs=512 count=1000 2>&1 | grep copied
/ # dd if=/dev/zero of=/tmp/test2.img bs=512 count=1000 2>&1
1000+0 records in
1000+0 records out

while at the host system it works

$ dd if=/dev/zero of=/tmp/test2.img bs=512 count=1000 2>&1 | grep copied
512000 bytes (512 kB, 500 KiB) copied, 0.00896706 s, 57.1 MB/s

host:

dd --v
dd (coreutils) 8.30
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Paul Rubin, David MacKenzie, and Stuart Kemp.

container:

/ # dd --v

BusyBox v1.31.1 () multi-call binary.

Usage: dd [if=FILE] [of=FILE] [ibs=N obs=N/bs=N] [count=N] [skip=N] [seek=N]
        [conv=notrunc|noerror|sync|fsync]
        [iflag=skip_bytes|fullblock] [oflag=seek_bytes|append]

Copy a file with converting and formatting

        if=FILE         Read from FILE instead of stdin
        of=FILE         Write to FILE instead of stdout
        bs=N            Read and write N bytes at a time
        ibs=N           Read N bytes at a time
        obs=N           Write N bytes at a time
        count=N         Copy only N input blocks
        skip=N          Skip N input blocks
        seek=N          Skip N output blocks
        conv=notrunc    Don't truncate output file
        conv=noerror    Continue after read errors
        conv=sync       Pad blocks with zeros
        conv=fsync      Physically write data out before finishing
        conv=swab       Swap every pair of bytes
        iflag=skip_bytes        skip=N is in bytes
        iflag=fullblock Read full blocks
        oflag=seek_bytes        seek=N is in bytes
        oflag=append    Open output file in append mode
        status=noxfer   Suppress rate output
        status=none     Suppress all output

N may be suffixed by c (1), w (2), b (512), kB (1000), k (1024), MB, M, GB, G

they are in fact, different

For anyone searching this question:

the DD used was being used with BusyBox. The third line is an optional output which is defined when compiling BusyBox from Source. The pre compiled versions have this disabled

ENABLE_FEATURE_DD_THIRD_STATUS_LINE must be defined.

see https://git.busybox.net/busybox/tree/coreutils/dd.c line 166.

#if ENABLE_FEATURE_DD_THIRD_STATUS_LINE
# if ENABLE_FEATURE_DD_STATUS
    if (G.flags & FLAG_STATUS_NOXFER) /* status=noxfer active? */
        return;
    //TODO: should status=none make dd stop reacting to USR1 entirely?
    //So far we react to it (we print the stats),
    //status=none only suppresses final, non-USR1 generated status message.
# endif
    fprintf(stderr, "%llu bytes (%sB) copied, ",
            G.total_bytes,
            /* show fractional digit, use suffixes */
            make_human_readable_str(G.total_bytes, 1, 0)
    );
    /* Corner cases:
     * ./busybox dd </dev/null >/dev/null
     * ./busybox dd bs=1M count=2000 </dev/zero >/dev/null
     * (echo DONE) | ./busybox dd >/dev/null
     * (sleep 1; echo DONE) | ./busybox dd >/dev/null
     */
    seconds = (now_us - G.begin_time_us) / 1000000.0;
    bytes_sec = G.total_bytes / seconds;
    fprintf(stderr, "%f seconds, %sB/s\n",
            seconds,
            /* show fractional digit, use suffixes */
            make_human_readable_str(bytes_sec, 1, 0)
    );
#endif
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM