Проблема в том, что вы не заключили в кавычки переменную $ENV
. Как объясняется в man bash
:
Заключение символов в двойные кавычки сохраняет буквальное значение всех символов внутри кавычек, за исключением $, `, \, и, когда включено расширение истории, ! Символы $ и ` сохраняют свое особое значение внутри двойных кавычек. Символ обратная косая черта сохраняет свое специальное значение только тогда, когда за ней следует один из следующих символов: $, `, ", \, или .
Таким образом, заключая последовательность типа \n
в двойные кавычки, вы сохраняете ее значение. Вот почему, когда \n
не заключено в кавычки, n
является обычным n
:
$ printf \n
n$
В то время как, когда заключено в кавычки:
$ printf "\n"
$
Переменная без кавычек в bash вызывает оператор split+glob. Это означает, что переменная разделяется на пробельные символы (или на то, что установлено специальной переменной $IFS
) и каждое полученное слово используется как glob (оно будет расширяться, чтобы соответствовать всем совпадающим именам файлов). Ваша проблема заключается в части "split".
Для иллюстрации возьмем более простую многострочную переменную:
$ var=$(printf "foo\nbar\n")
Теперь, используя set -x
функцию отладки оболочки, вы можете увидеть, что именно происходит:
$ echo $var
+ echo foo bar
foo bar
$ echo "$var"
+ echo 'foo
bar'
foo
bar
Как вы можете видеть выше, echo $var
(без кавычек) подвергает $var
сплиту+glob, так что в результате получаются две отдельные строки, foo
и bar
. Новая строка была съедена этим split+glob. Когда переменная была заключена в кавычки, она не подвергалась split+glob, новая строка сохранялась и, поскольку она заключена в кавычки, также правильно интерпретировалась и выводилась на печать.
Следующая проблема заключается в том, что printf
не похож на echo
. Он не просто печатает все, что вы ему дадите, он ожидает строку форматирования. Например, printf "color:%s" "green"
выведет color:green
, потому что %s
будет заменен на green
.
Он также игнорирует любой ввод, который не укладывается в заданную ему строку формата. Так, если вы запустите printf foo bar
, printf
будет рассматривать foo
как строку форматирования, а bar
как переменную, которую он должен отформатировать. Поскольку нет %s
или эквивалента, который можно заменить на bar
, bar
игнорируется и печатается только foo
:
$ printf $var
+ printf foo bar
foo
Вот что произошло, когда вы выполнили printf $ENV_BEFORE
. Поскольку переменная не была заключена в кавычки, разделительный глобус эффективно заменил новые строки пробелами, и printf
напечатал только первое попавшееся "слово".
Чтобы сделать это правильно, используйте форматные строки и всегда заключайте переменные в кавычки:
printf '%s\n' "$ENV_BEFORE"
error: no such devices 4E...111F
error: not a partition
error: device format "lvmid/ozz..." invalid must be (f|h)dN, with 0 <= N < 120.
error: invalid signature
Эти сообщения поступают из GRUB, поэтому в этот момент initramfs еще даже не загружен.
Проблема, по-видимому, заключается в том, что BIOS вашей системы не может получить доступ к устройству NVMe во время загрузки (, по крайней мере, не в устаревшем режиме BIOS ).
Поскольку в основном все системы со встроенными -слотами M.2 для накопителей NVMe являются достаточно новыми, чтобы иметь прошивку UEFI, некоторые поставщики системной прошивки, похоже, решили реализовать поддержку загрузки NVMe только в основном режиме UEFI. . Когда ваш Linux запущен, он прекрасно видит диск NVMe, и поэтому update-grub
может его прочитать, но во время загрузки ваш GRUB использует устаревшие функции BIOS для перечисления системных дисков, а для устаревшего BIOS — Диска NVMe просто не существует. Если соответствующее расширение BIOS для доступа к NVMe недоступно, BIOS видит диск NVMe как универсальное устройство PCI/PCIe, не имеющее вообще ничего общего с какими-либо дисковыми устройствами.
Вам следует очень внимательно проверить настройки BIOS. :Если есть параметр, относящийся к поддержке загрузки NVMe, и он в настоящее время отключен, попробуйте включить его. Но если ваш накопитель NVMe находится на дополнительной плате -, он, скорее всего, не будет загружаться в устаревшем BIOS на материнской плате, на которой нет встроенных -слотов NVMe, если только карта не включает ПЗУ расширения BIOS, которое обеспечит необходимые Процедуры BIOS для доступа к диску NVMe.