Экспортировать не заданную переменную при передаче ее в другую команду

Я, кажется, нашел способ приблизить прогресс 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%. Думаю, достаточно точно, чтобы быть полезным.

0
27.10.2021, 18:46
2 ответа

Обычно части конвейера (, за исключением последней, в некоторых оболочках )выполняются в подоболочках, то есть оболочка разветвляет свою копию для каждой из них, а затем каждая копия обрабатывает команду в этой части и выполняет любые внешние команды (вроде 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, но не в другом, казалось бы, похожем цикле? .

1
27.10.2021, 19:37

Перепишите код таким образом:

export USER=new
env | grep $USER

Чтобы получить содержимое переменной USER, вам нужно $ранее. И канал на exportне имеет смысла, так как команда exportне имеет никакого вывода в STDOUT

0
27.10.2021, 19:39

Теги

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