Hauppauge quadHD завершается сбоем при прохождении интерфейса PCI на Dell R710

Это очень надежно и поддерживается всеми версиями ядра, которые поддерживают initrd, AFAIK. Это особенность архивов cpio, из которых состоят initramfs. cpio просто продолжает извлекать свои входные данные.... мы можем знать, что файл представляет собой два архива cpio один за другим, но cpio просто воспринимает их как один входной поток.

Debian советует использовать именно этот метод (добавление ещё одного cpio в initramfs) для добавления binary-blob прошивок в initramfs их установщика. Например:

DebianInstaller / NetbootFirmware | Debian Wiki

Initramfs по сути является конкатенацией gzipped cpio архивов которые извлекаются на ramdisk и используются как раннее пользовательское пространство ядром ядром Linux. initrd.gz установщика Debian на самом деле представляет собой один gzipped cpio архив, содержащий все файлы, необходимые программе установки при во время загрузки. Простым добавлением другого gzipped cpio архива - содержащий файлы прошивки, которых нам не хватает, мы получаем шоу на в путь!

3
09.08.2018, 06:56
3 ответа

Нечто подобное можно сделать в одной строке с:

$ a=-00100; a=${a%"${a#[+-]}"}${a#"${a%%[!0+-]*}"}; a=${a:-0}
$ echo "$a"
-100

Для 1000 повторений требуется всего 0,0482, что в 100 раз меньше, чем при использовании внешней программы.

Это основано на разложении двух двойных параметров:

  1. Извлечь знак :
    • ${a#[+-]}удалить первый символ, если это знак.
    • ${a%"${a#[+-]}"}сохраняет первый признак при условии, что это знак.
  2. Удалить все начальные знаки и/или нули :
    • ${a%%[!0+-]*}удалить, начиная с любого (, а не с 0 или + или-)до конца.
    • ${a#"${a%%[!0+-]*}"}удалить вышеперечисленное, т. е. все ведущие нули и знаки.

Это выбирает один знак и удаляет все ведущие нули. Однако позволяет (без ошибок):

  1. Несколько ведущих знаков.
  2. Любые символы после ведущих знаков и нулей.
  3. "Вне диапазона" (слишком большое )число.

Если эти тесты необходимы, продолжайте читать.


Количество знаков можно проверить с помощью:

signs=${a%%[!+-]*} 
[ ${#signs} -gt 1 ] && echo "$0: Invalid number $a: Too many signs"

Тип допустимых символов можно было проверить с помощью:

num=${a#"${a%%[!0+-]*}"}

any=${num%%[!0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@_]*}
[ "$any" != "$num" ] && echo "$0: Invalid number $a"

hex=${num%%[!0123456789abcdefABCDEF]*}
[ "$hex" != "$num" ] && echo "$0: Invalid hexadecimal number $a"

dec=${num%%[!0123456789]*}
[ "$dec" != "$num" ] && echo "$0: Invalid decimal number $a"

И, наконец, мы можем воспользоваться возможностью printfпечатать предупреждение о числах «вне диапазона» (только для баз, которые printf понимает):

printf '%d' $sign$dec >/dev/null                            # for a decimal number
printf '%d' "${sign}0x$hex" >/dev/null                      # for hex numbers

Да, все printf используют %d, это не опечатка.

И да, все вышеперечисленное работает в большинстве оболочек, имеющих printf.

1
27.01.2020, 21:25

Обратите внимание, что хотя $((010))требуется POSIX для расширения до 8, некоторые оболочки не делают этого по умолчанию (или только в некоторых контекстах ), если только не в режиме соответствия, поскольку это функция. Вы обычно не хотите.

При zshэто контролируется параметром octalzeroes(, отключенным по умолчанию, за исключением эмуляции sh/ksh ).

$ zsh -c 'echo $((010))'
10
$ zsh -o octalzeroes -c 'echo $((010))'
8
$ (exec -a sh zsh -c 'echo "$((010))"')
8

В mkshэто контролируется параметром posix, (отключенным по умолчанию):

$ mksh -c 'echo "$((010))"'
10
$ mksh -o posix -c 'echo "$((010))"'
8

В bash нет возможности отключить его, но вы можете использовать синтаксис $((10#010))ksh для принудительной интерпретации в десятичном формате (также работает в ksh и zsh ), хотя в bashи mksh -o posix, $((10#-010))не работает (рассматривается как 10#0 - 010, как видно из расширения $((-10#-010)), дающего -8), вам нужно$((-10#010))(или $((- 10#010))для совместимости с zsh, который жалуется о том, что -10является недействительной базой ).

$ bash -c 'echo "$((10#010))"'
10

С ksh93сравните:

$ ksh93 -c 'echo "$((010))"'
8
$ ksh93 -c '((a = 010)); echo "$a"'
8

с:

$ ksh93 -c 'a=010; echo "$((a))"'
10
$ ksh93 -c 'printf "%d\n" 010'
10
$ ksh93 -c 'let a=010; echo "$a"'
10
$ ksh93 -c 'echo "$((010e0))"'
10
$ ksh93 -o letoctal -c 'let a=010; echo "$a"'
8

Так что, по крайней мере, если вы программируете конкретно для какой-либо из этих оболочек, есть способы обойти эту «ошибку».

Но ни один из них не поможет при написании переносимого сценария POSIX, и в этом случае вы захотите удалить начальные нули, как вы показали.

2
27.01.2020, 21:25

Вот ваш пример x1000 в моей системе:

$ cat shell.sh
#!/bin/dash
q=1
while [ "$q" -le 1000 ]
do
  z=-00100
  z=${z%"${z#[+-]}"}${z#"${z%%[!0+-]*}"}
  z=${z:-0}
  echo "$z"
  q=$((q + 1))
done

Результат:

$ time./shell.sh >/dev/null
real    0m0.047s

Теперь я возражаю против примера с sed. Я вижу пример с файлом, но я не видя четкой причины, по которой использование файла неприемлемо. также пример с каналом проблематично, потому что канал не нужен -и не вызывает sed 1000 раз. если вы просто не можете использовать файл по какой-либо причине -, здесь будет документ отлично:

cat > sed.sh <<alfa
sed 's/^0*//' <<bravo
$(yes 00100 | head -1000)
bravo
alfa

Результат:

$ time./sed.sh >/dev/null
real    0m0.047s

Таким образом, в моей системе это точно такая же скорость без суеты.

0
27.01.2020, 21:25

Теги

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