Создайте случайные данные с dd и получите “частичное предупреждение чтения”. Данные после предупреждения, теперь действительно случайного?

Ну, я переехал от операторов выбора к egrep, поскольку это, казалось, помогло мне. У меня были проблемы с передающими параметрами в мою функцию..., таким образом, я просто вышел из выполнения этого. Не лучшее, но я заставил это работать. Дальнейшие мысли о нем?

#!/bin/ksh


#################################################################################
#                        PARAMETERS & VARIABLES SECTION                         #
#################################################################################

DBI_LOC="DBI/InstallCollector/dbi_collector/bin"

#Put input option to upper case.
OPTION=$( echo "$1" | tr "[:lower:]" "[:upper:]" )

#################################################################################
#                              FUNCTION SECTION                                 #
#################################################################################

parseresults() {

    if [ "${OPTION}" = "START" ] ; then
        echo "Success"
        return 0
    else
        echo ${RESULT} | egrep -s ".*DBI.*not\srunning.*"
        if [ $? = 0 ] ; then
            echo "Collector is already down. Continuing..."
            return 0
        fi

        echo ${RESULT} | egrep -s ".*DBI.*COMPLETE.*"
        if [ $? = 0 ] ; then
            echo "Success shutting down collector. Continuing..."
            return 0
        fi

        echo "Error shutting down the collector. Exiting with error."
        return 1
    fi
}

#################################################################################
#                             MAIN SCRIPT SECTION                               #
#################################################################################



case "${OPTION}" in
    "START")
        echo "Starting the collectors..."
        RESULT=$(ksh ~/${DBI_LOC}/start_dbi_collector.sh)
        ;;
    "STOP")
        echo "Stopping the collectors..."
        RESULT=$(ksh ~/${DBI_LOC}/stop_dbi_collector.sh)
        ;;
    *)
        echo "Error: No Parameter specified. Must be either start or stop"
        exit 1
        ;;
esac

echo ${RESULT}
parseresults 

if [ ! $? = 0 ] ; then
    exit 1
fi

echo
echo
16
09.04.2014, 18:15
3 ответа
[114937]Итог: [115420]dd[115421] - это капризный инструмент, который трудно использовать правильно. Не используйте его, несмотря на многочисленные учебники, которые вам об этом говорят. [115422]dd[115423] имеет вибрацию "уникс уличный кредит" - но если вы действительно понимаете, что делаете, вы поймете, что не должны прикасаться к нему 10-футовым полюсом.

dd[115425] делает один вызов на [115426]прочитанный[115427] системный вызов на блок (определяемый значением [115428]bs[115429]). Нет гарантии, что системный вызов [115430]read[115431] возвращает столько данных, сколько указано в указанном размере буфера. Это обычно работает для обычных файлов и блочных устройств, но не для труб и некоторых символьных устройств. См. [115432]Когда dd подходит для копирования данных? (или, когда read() и write() partial)[115433] для получения дополнительной информации. Если системный вызов [115434]read[115435] возвращает менее одного полного блока, то [115436]dd[115437] передает частичный блок. Он по-прежнему копирует указанное количество блоков, поэтому общее количество переданных байтов меньше запрошенного.

  • Предупреждение о "частичном считывании" говорит именно об этом: одно из считываний было частичным, поэтому [115438]dd[115439] передал неполный блок. В счетах блоков [115440]+1[115441] означает, что один блок был прочитан частично; так как выходной счетчик равен [115442]+0[115443], все блоки были записаны как прочитанные.
  • Это не влияет на случайность данных: все байты, которые записывает [115444]dd[115445], являются байтами, которые он прочитал из [115446]/dev/urandom[115447]. Но вы получили меньше байт, чем ожидалось.

/dev/urandom[115449] Linux's [115448]/dev/urandom[115449] удовлетворяет произвольные большие запросы (source:

extract_entropy_user

в [115452]драйверах/char/random.c[115453]), так что [115454]dd[115455] обычно безопасен при чтении из него. Однако для чтения больших объемов данных требуется время. Если процесс получает сигнал, системный вызов [115456]read[115457] возвращается до заполнения своего выходного буфера. Это нормальное поведение, и приложения должны вызывать [115458]read[115459] в цикле; [115460]dd[115461] этого не делает, по историческим причинам ([115462]dd[115463] происхождение неясное, но, похоже, оно началось как средство доступа к лентам, которые имеют специфические требования, и никогда не были приспособлены для использования в качестве инструмента общего назначения). Когда вы проверяете прогресс, он посылает [115464]dd[115465] обрабатывать сигнал, который прерывает чтение. У вас есть выбор между тем, чтобы знать, сколько байт [115466]dd[115467] всего скопировано (не прерывайте его - нет проверки прогресса, нет приостановки), или чтобы знать, сколько байт [115468]dd[115469] скопировано до сих пор, и в этом случае вы не можете знать, сколько еще байт он скопирует.

Версия

dd[115989] в GNU coreutils[115471] (как на не встроенном Linux и на Cygwin) имеет флаг [115472]fulllblock[115473], который говорит [115474]dd[115475] вызывать [115476] читать [115477] в цикле (и то же самое для [115478] писать [115479]) и таким образом всегда передавать полные блоки. Сообщение об ошибке предполагает, что вы используете его; вы всегда должны использовать его (как во флагах ввода, так и на выходе), за исключением особых обстоятельств (в основном при доступе к лентам) - если вы используете [115480]dd[115481] вообще, то есть: как правило, есть решения и получше (см. ниже).

Другой возможный способ убедиться в том, что [115482]dd[115483] сделает, - это передать блок размером 1. Тогда вы можете сказать, сколько байт было скопировано со счета блока, хотя я не уверен, что произойдет, если [115484]чтение [115485] будет прервано до чтения первого байта (что на практике маловероятно, но может произойти). Однако, даже если это и работает, то очень медленно.

Общий совет по использованию [115486]dd[115487] - это [115488] не использовать [115990]dd

. Хотя [115490]dd[115491] часто рекламируется как низкоуровневая команда для доступа к устройствам, на самом деле это не так: вся магия происходит в файле устройства (часть [115492]/dev/...[115493]), [115494]dd[115495] - это обычный инструмент с высоким потенциалом неправильного использования, приводящего к потере данных. В большинстве случаев есть более простой и безопасный способ делать то, что вы хотите, по крайней мере, на Linux.

Например, чтобы прочитать определенное количество байт в начале файла, просто позвоните [115496]head[115497]:

Я сделал быстрый тест на своей машине и не заметил разницы в производительности между [115498]dd[115499] с большим размером блока и [115500]head[115501].

Если вам нужно пропустить некоторые байты в начале, вставьте [115502] хвост [115503] в [115504] голову [115505]:

Если вы хотите увидеть прогресс, позвоните [115506]lsof[115507], чтобы увидеть смещение файла. Это работает только на обычном файле (выходной файл на вашем примере), а не на символьном устройстве.

Вы можете вызвать

pv

, чтобы получить отчет о ходе работы (лучше, чем [115510]dd[115511]), за счет дополнительного пункта в процессе работы (по производительности, он едва заметен).[114962].

39
27.01.2020, 19:48
[114330] Предупреждение возникает, когда [114696]dd[114697] не может получить достаточно данных для заполнения блока за одно считывание. Это происходит с неустойчивыми или медленными источниками данных, или источниками, которые записывают данные в меньшем размере, чем запрошенный вами размер блока.[12135]Проблемы с целостностью данных нет, но проблема в том, что [114698]dd[114699] считает частичное чтение еще как блок чтения.[12136]Если вы не используете опцию [114700]count[114701], предупреждение едва ли имеет значение, это всего лишь рассмотрение производительности. Но с помощью [114702]count[114703] вы не получите запрашиваемого объема данных. Из-за частичного считывания [114704]из [114705] будет меньше, чем [114706]счет*bs[114707] в конце.[12137] Поэтому при использовании [114708]счетчика[114709], технически всегда следует использовать [114710]iflag=fullblock[114711].[12138]Число [114712]+x[114713] должно быть количеством частичных блоков.[114339].
9
27.01.2020, 19:48
< /dev/urandom \
dd ibs=4k obs=64k |
dd bs=64k count=16000000 >file

^ Это просто сработает. Дезинформация здесь явно ложная. Буферы dd являются явными , поэтому для буферизации ввода до count вхождений необходимо явно буферизовать. Это все. Не покупай фуд.

-3
27.01.2020, 19:48

Теги

Похожие вопросы