Утилита dd выводит разные строки под одной и той же командой для sh и bash, как заставить вывод последней строки внутри контейнера docker? - PullRequest
0 голосов
/ 27 февраля 2020

Внутри контейнера docker я проверяю выполнение строки

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

. Я сверляю в контейнер двумя способами.

1) классическим является docker exec -it 2b65c84ddce2 /bin/sh

выполнение строки внутри содержимого, унаследованного от альпийского я приветствую /bin/sh: syntax error: unexpected redirection из-за чего-то около >(

2) когда я ввожу контейнер в bash исполнитель, как docker exec -it 2b65c84ddce2 /bin/bash

dd if=/dev/zero of=/tmp/test2.img bs=512 count=1000 2> >( grep copied ) не возвращает никакого вывода dd if=/dev/zero of=/tmp/test2.img bs=512 count=1000 возвращает только 2 строки вывода, в то время как ожидание равно 3:

1+0 records in
1+0 records out

На уровне хоста та же самая команда dd возвращает 3 строки, подобные этой:

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

и с перенаправлением вывод является последней строкой:

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

Так как я могу получить последнюю строку вывода dd изнутри контейнера docker?

PS.

Перенаправление stderr на стандартный вывод в целом не помогает:

/ # 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

в то время как в хост-системе это работает

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

Автор Paul Rubin, David MacKenz ie и Стюарт Кемп.

контейнер:

/ # 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

они на самом деле отличаются лор

1 Ответ

1 голос
/ 27 февраля 2020

Для тех, кто ищет этот вопрос:

используемый DD использовался с BusyBox. Третья строка - необязательный вывод, который определяется при компиляции BusyBox из Source. Предварительно скомпилированные версии имеют отключенную

ENABLE_FEATURE_DD_THIRD_STATUS_LINE должна быть определена.

см. https://git.busybox.net/busybox/tree/coreutils/dd.c строка 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
}
...