Я, кажется, нашел способ приблизить прогресс ext4lazyinit.
TL;DR :см. Сценарий ниже.
Этот метод предполагает, что диск никогда не отключался (и система не перезагружалась )с момента самого первого монтирования раздела, и что вы записали в раздел ровно столько данных, сколько находится в используйте на нем (, чтобы не удалять и не изменять файлы ).
Шаг 1:Сравните размер раздела в fdisk (, преобразованный в килобайты ), с количеством блоков по 1 КБ -, показанным в df. Вычтите (количество 1K -блоков )из (размера раздела в килобайтах ), чтобы получить (примерный размер таблицы инодов ).
РЕДАКТИРОВАТЬ :Пример, fdisk:
Sector size (logical/physical): 512 bytes / 4096 bytes
(...omitted...)
Device Start End Sectors Size Type
/dev/sdd1 2048 11720978398 11720976351 5.5T Linux filesystem
дф:
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/workbackup 5813233164 1217095176 4596121604 21% /mnt/backup_work
11720976351 сектор *512 байт/сектор/1024 = 5860488175,5 кБ (почти 5,5 ТиБ, как говорит fdisk ). Минус df 5813233164 равен 47255011,5 КБ (около 45 ГБ )для приблизительного размера таблицы инодов.
Шаг 2:Получить (общее количество килобайт, записанное в раздел):
awk '{ print $3"\t"$10 }' /proc/diskstats
Выберите правильную строку для своего раздела и преобразуйте ее в киБ.
РЕДАКТИРОВАТЬ :пример:
sdb 260040
sdb1 260040
sdd 2530109116
sdd1 2530108940
При использовании sdd1 в моем случае общее количество записанных килобайт = 2530108940 секторов *512 байт/сектор / 1024 = 1265054470 килобайт (почти 1,2 ТиБ ).
Шаг 3:Требуется только в том случае, если вы уже записали какие-либо данные в файловую систему. Вычтите (количество 1K -ИСПОЛЬЗУЕМЫХ блоков, показанное в df )из (общего количества КБ, записанных в раздел ), чтобы получить (приблизительно КБ, записанных в таблицу инодов ).
РЕДАКТИРОВАТЬ :пример :приблизительное количество килобайт, записанное в таблицу inode = 1265054470 (из шага 2)-1217095176 (см. вывод df на шаге 1 )= 47959294 килобайт (45,7 ГиБ)
Шаг 4:Разделите (приблизительное количество килобайт, записанное в таблицу инодов ), на (приблизительный размер таблицы инодов в килобайтах )и умножьте на 100, чтобы получить прогресс в процентах.
РЕДАКТИРОВАТЬ :пример :приблизительный прогресс = 47959294 / 47255011,5 *100% = 101,5%
Скрипт
Или написать это как неполный скрипт (, где я отказываюсь писать скрипт для вызова fdisk из соображений безопасности):
let sectorsize=$(cat /sys/block/sda/queue/hw_sector_size)
let partsize=$2*$sectorsize/1024
let fssize=$(df -- "$3" | tail -n -1 | awk '{print $2}')
let approxinodetablesize=$partsize-$fssize
let tkw=$(awk "/$1/"' {print $10}' /proc/diskstats | head -n 1)*$sectorsize/1024
let used=$(df -- "$3" | tail -n -1 | awk '{print $3}')
let tkw_inodetable=$tkw-$used
echo "Approximate progress: $(bc -l <<< "$tkw_inodetable*100.0/$approxinodetablesize") %"
Вызов с $1 = "имя раздела" (например. sdd1 ), $2 = "сектора раздела в соответствии с fdisk", $3 = "точка монтирования без косой черты"
Результаты испытаний
Я проверил свой метод только один раз. Настройка:
Раздел 6 ТБ
шифрование с использованием cryptsetup
файловая система создана с параметрами по умолчанию, кроме -m 0
279 ГиБ файлов, записанных в раздел до завершения ext4lazyinit.
Результат:показание 99,7 % на момент завершения:-)
РЕДАКТИРОВАТЬ :тот же диск, после записи на него почти еще одного ТиБ данных, теперь дает оценку 101,5%. Думаю, достаточно точно, чтобы быть полезным.
Обычно части конвейера (, за исключением последней, в некоторых оболочках )выполняются в подоболочках, то есть оболочка разветвляет свою копию для каждой из них, а затем каждая копия обрабатывает команду в этой части и выполняет любые внешние команды (вроде cat
там ). Основная оболочка, которая продолжает следующую команду (, другой конвейер )не видит измененного значения.
(И в любом случае, каким, по вашему мнению, должно быть значение var
после такой команды, как var=foo | var=bar
?)
Обычно это происходит, когда у вас есть назначения переменных в последней части конвейера, например
n=0
some command | while read line; do n=$((n+1)); done
, что оставило бы n
установленным на 0
во многих оболочках, но не во всех :ksh и zsh запускают последнюю часть в основной оболочке, и у Bash есть опция для этого. Это обсуждается в . Почему моя переменная локальна в одном цикле while read, но не в другом, казалось бы, похожем цикле? .
Перепишите код таким образом:
export USER=new
env | grep $USER
Чтобы получить содержимое переменной USER
, вам нужно $
ранее. И канал на export
не имеет смысла, так как команда export
не имеет никакого вывода в STDOUT