Как «командная строка» передается от загрузчика (grub) к ядру (linux)?

Помещение

Вы не должны сталкиваться с этой ошибкой длятолько15k файлов с этим форматом имени [ 1 , 2 ] .

Если вы запускаете это расширение из другого каталога и вам нужно добавить путь к каждому файлу, размер вашей команды будет больше, и, конечно, это может произойти.

Решение запустите команду из этого каталога.

(cd That/Directory ; cat file_{1..2000}.pdb >> file_all.pdb )

Лучшее решение Если вместо этого я угадал и вы запустите его из каталога, в котором находятся файлы...
ИМХО лучшее решение это Stéphane Chazelas:

seq -f 'file_%.17g.pdb' 15000 | xargs cat > file_all.pdb

с помощью printf или seq; протестировано на 15k файлах с только их номером внутри предварительно -кэшированного, в настоящее время он даже самый быстрый (и, кроме OP, из того же каталога, в котором находятся файлы ).

Еще несколько слов

У вас должна быть возможность более длинного перехода к командной строке оболочки.
Ваша командная строка имеет длину 213914 символов и содержит 15003 слова
cat file_{1..15000}.pdb " > file_all.pdb" | wc

... даже добавление 8 байтов для каждого слова составляет 333 938 байтов (0,3M )намного ниже, чем 2097142 (2,1M ), о которых сообщает ARG_MAXна ядре 3.13.0 или немного меньший 2088232 сообщается как «Максимальная длина команды, которую мы могли бы фактически использовать» отxargs --show-limits

Посмотрите в своей системе вывод

getconf ARG_MAX
xargs --show-limits

Решение на основе лени

В подобных случаях я предпочитаю работать с блоками, даже потому, что обычно получается решение, эффективное по времени.
Логика (, если таковая имеется ), мне лень писать 1...1000 1001..2000 и т.д. и т.п...
Поэтому я прошу сценарий сделать это за меня.
Только после того, как я проверил правильность вывода, я перенаправляю его в скрипт.

... но Лень — это состояние души .
Так как у меня аллергия наxargs(я действительно должен был использовать xargsздесь )и я не хочу проверять, как его использовать, я пунктуально заканчиваю изобретать велосипед как в примерах ниже (tl; др ).

Обратите внимание, что поскольку имена файлов контролируются (без пробелов, новых строк... )вы можете легко использовать что-то вроде сценария ниже.

тл;др

Версия 1 :передавать в качестве необязательных параметров 1-й номер файла, последний, размер блока, выходной файл

#!/bin/bash
StartN=${1:-1}          # First file number
EndN=${2:-15000}        # Last file number
BlockN=${3:-100}        # files in a Block 
OutFile=${4:-"all.pdb"} # Output file name

CurrentStart=$StartN 
for i in $(seq $StartN $BlockN $EndN)
do 
  CurrentEnd=$i ;  
    cat $(seq -f file_%.17g.pdb $CurrentStart $CurrentEnd)  >> $OutFile;
  CurrentStart=$(( CurrentEnd + 1 )) 
done
# Here you may need to do a last iteration for the part cut from seq
[[ $EndN -ge $CurrentStart ]] && 
    cat $(seq -f file_%.17g.pdb $CurrentStart $EndN)  >> $OutFile;

Версия 2

Вызов bash для расширения (немного медленнее в моих тестах ~20% ).

#!/bin/bash
StartN=${1:-1}          # First file number
EndN=${2:-15000}        # Last file number
BlockN=${3:-100}        # files in a Block 
OutFile=${4:-"all.pdb"} # Output file name

CurrentStart=$StartN 
for i in $(seq $StartN $BlockN $EndN)
do 
  CurrentEnd=$i ;
    echo  cat file_{$CurrentStart..$CurrentEnd}.pdb | /bin/bash  >> $OutFile;
  CurrentStart=$(( CurrentEnd + 1 )) 
done
# Here you may need to do a last iteration for the part cut from seq
[[ $EndN -ge $CurrentStart ]] && 
    echo  cat file_{$CurrentStart..$EndN}.pdb | /bin/bash  >> $OutFile;

Конечно, вы можете пойти дальше и полностью избавиться от seq[ 3 ](из coreutils )и работать напрямую с переменными в bash или использовать python, или скомпилируйте программу переменного тока, чтобы сделать это [ 4 ] ...

2
20.10.2019, 17:51
2 ответа

Grub реализует спецификацию мультизагрузки . Когда он загружает ядро ​​и передает ему управление, он передает указатель на информационную структуру в памяти. Одним из полей в этой структуре является командная строка.

Ядро Linux имеет собственный протокол загрузки , но командная строка обрабатывается аналогичным образом :загрузчик оставляет ее в памяти и заполняет различные поля в структуре данных ядра, которые позволяют ядру найти его.

4
27.01.2020, 21:58

После того, как загрузчик выполнит служебную загрузку, он запускает минимальную среду ОС, обычно основанную на initrd.img или initramfs. Параметры ядра, которые вы видите в файле grub, относятся к ядру, которое загружается после этой минимальной среды. Обычно для всех намерений и целей, когда вы запускаете mkinitrd, для настройки этого образа initrd используются разумные настройки, выбранные из /etc.

К тому времени, когда происходит обычная последовательность загрузки, первоначальная среда отбрасывается и используется обычное ядро. Следует отметить, что драйверы, запущенные в initrd, могут оставаться резидентными при обычном выполнении, что может быть источником больших головных болей.

0
27.01.2020, 21:58

Теги

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