У меня есть следующий код как часть сценария оболочки:
while [ $(ps -ef | awk '{print $2}' | grep -F "$CPPID") ]; do
sleep 10
awk -v "usbsize=$(/bin/df | grep -F $DEVICEMOUNTPOINTQ | awk '{print $3}')" -v "isosize=$(/bin/df | grep -F $ISOMOUNTPOINTQ | awk '{print $3}')" 'BEGIN { printf "%.1f", 100 * usbsize / isosize }' && echo "% copied..."
done
Это мониторинг, cp
выполняющий следующую операцию:
cp -a "$ISOMOUNTPOINT"/* "$DEVICEMOUNTPOINT"
И это работает нормально по большей части, пока
90.5% copied...
94.2% copied...
97.8% copied...
101.6% copied...
102.7% copied...
Почему это превышает 100% размера источника? Копия с ISO-образа, смонтированного в петлю, на раздел в формате NTFS на флэш-накопителе USB. Я предполагаю, что это, вероятно, вещь файловой системы?
Чего не хватает в моем примере, чтобы размеры соответствовали друг другу, чтобы при cp
завершении он копировался на 100%, а не на 103%?
Благодарю.
Re: Баунти
Я назначу вознаграждение первому лицу, предложившему решение, аналогичное приведенному выше коду, которое соответствует следующим критериям:
- Скрипт должен быть в состоянии обнаружить копирование в соотношении 1: 1
- Скрипт не должен отображать значение, превышающее 100%, однако ...
- Сценарий не должен просто ограничивать отображение на 100%, когда оно превышает его.
Если размер данных делает на самом деле отличается от источника к месту назначения по какой - то причине, то я хотел бы сценарий , который замечает это и по- прежнему отображает реальное соотношение скопированы.
источник
Ответы:
Вот ваш код упрощен и сделан более читабельным:
Ваша последняя
awk
строка может быть заменена этими двумя:Тогда вы можете сделать это прямо перед этим
printf
утверждением:и добавить
wait $CPPID
сразу после окончанияwhile
цикла. Это остановит процесс печати после достижения 100%.См. Управление процессами относительно надежности PID (они перерабатываются).
Возможно, проблема, которую вы видите, связана с использованием «используемого» значения целевой файловой системы, а не с разницей в текущем значении и начальном значении.
Попробуйте добавить такую строку перед
while
циклом:и измените строку внутри цикла на:
Конечно, всего этого можно избежать, если использовать
rsync --progress
вместоcp
.Редактировать:
Также попробуйте это в
while
цикле, как показано выше, чтобы увидеть, какие числа используются в расчете. Это может дать ключ к пониманию того, что происходит:источник
bc
еще одна опция для выполнения математических операций с плавающей точкой, которая может привести к более коротким командам. Я просто считал само собой разумеющимся, что это вездесуще. AWK подходит для этой цели./bin/df $DEVICEMOUNTPOINTQ
и/bin/df $ISOMOUNTPOINTQ
выводить? Это одна строка заголовка, за которой следует что-то вроде/dev/xxx 1111 2222 3333 44% /mountpoint
? Если вы добавитеecho "[$DEVICEMOUNTPOINTQ] [$ISOMOUNTPOINTQ]"
перед командой AWK, что она выводит? Кстати, у меня есть опечатка в этом фрагменте. В конце есть двойная кавычка. Попробуйте удалить это.Первое, что я могу сделать, это то, что это будет в значительной степени зависеть от типа файлов в исходном каталоге. Я думаю, что вероятным виновником являются редкие файлы. Разреженный файл - это файл, где stat.st_size! = (Stat.st_blksize * stat.st_blocks); то есть общий размер файла больше, чем количество блоков данных, связанных с индексом файла. Любые нераспределенные блоки считываются системными вызовами как блок нулей. Поэтому, когда вы используете cp (1) для разреженного файла, конечный файл будет содержать больше блоков (содержащих только нули), чем исходный файл. Команды du (1) и df (1) определяют количество блоков, а не размер файла (ов). Базовые файлы часто создаются как разреженные файлы, так как им может потребоваться отобразить память. Этот тип файла полезен для создания образов дисков, например, для создания диска виртуального хоста размером 15 ГБ. Было бы очень расточительно выделить все блоки во время создания; размер (st_size) может составлять 15 ГБ, но фактическое количество блоков может начинаться с 0.
Это только один тип файла, который может взорваться при копировании. Не зная, что у вас есть в вашей файловой системе, трудно сказать, что еще может быть.
источник
Вы можете использовать rsync только в локальном режиме, где и у источника, и у места назначения нет имени «:», поэтому он ведет себя как улучшенная команда копирования. С параметром progress он отображает что-то похожее на это ( источник ):
Поскольку это не дает общий процент, другое решение может быть использовать этот скрипт ( источник ):
В бою:
Вы также можете взглянуть на файлы перемещения с индикатором выполнения, который подробно описывает, как добавить в cp и mv ключ -g, чтобы показать прогресс.
источник