Вопрос печати BASH (printf \\$(printf '%03o' $1))

2 вещи при условии, что вы ничего не сделали, кроме установки пакета:

  1. Для загрузки драйвера nvidia необходимо изменить файл xorg.conf. Driver "nvidia"Учтите, что через xorg.conf практически невозможно поговорить с кем-либо, поэтому для этого нужно написать сценарий.

  2. Настройка режима должна быть занесена в черный список в grub, а затем обновлена ​​в grub.

По какой-то необъяснимой причине, несмотря на десятилетия знаний, эти дистрибутивы по-прежнему не могут автоматизировать эти два действия, необходимые для загрузки несвободных драйверов. Как видите, все драйвера загружены на xorg, но xorg не знает, что он должен использовать nvidia, а не modesetting.

Они также не могут фактически проверить идентификатор шины фактической видеокарты/устройства, чтобы убедиться, что устанавливаемый драйвер является правильным драйвером. Это, как показано ниже, проблема, которая была полностью решена более 10 лет назад и которой просто не должно быть вообще. Но создатели пакета драйверов отказываются это делать. Например, у nvidia обычно поддерживается от 3 до 4 устаревших версий карт, и в основном тривиально проверить идентификатор установленной карты по этим спискам, чтобы убедиться, что вы устанавливаете правильный драйвер.

Вот почему в Xorg.0.log вы видите действия modeset и почти никаких действий nvidia

Меня постоянно огорчает, что эта проблема продолжает существовать в пакетах драйверов дистрибутивов, этому нет абсолютно никаких оправданий, для создания сценариев этих решений требуется всего несколько сотен строк кода, чтобы решить проблему для всех пользователей по всему миру. Альтернативное нерешение состоит в том, что пользователь за пользователем задает один и тот же вопрос из года в год, одну и ту же проблему с одним и тем же точным решением, как будто поддержка — это бесконечный товар, который можно просто предположить, когда решение есть и всегда было. чтобы написать его для всех пользователей.

[Обратите внимание, что эти решения не только могут быть полностью написаны сценариями, они были полностью написаны сценариями несколько раз, насколько мне известно,но сопровождающие дистрибутива упорно отказываются реализовывать эти решения в своей упаковке].

7
13.12.2019, 18:27
3 ответа

Внутренний printf '%03o' $1возвращает значение $1(, то есть 65 ), как восьмеричное значение (65 -> 101 ).

Внешний printf \\$(..)печатает символ, представленный восьмеричным значением.

См. man printfстроку:

\NNN byte with octal value NNN (1 to 3 digits)

Для printf '%d' "'$1"необходимо указать ', чтобы указать, что $1следует рассматривать как односимвольную константу, иначе printf выдаст ошибку, указывающую, что значение является недопустимым числом. Затем значение символьной константы используется printfдля печати в десятичном формате "%d"

.
5
28.04.2021, 23:26

printf '\101', где 101— восьмеричное число, выводит байт с этим значением.

При отправке на терминал ASCII это будет отображаться как A, так как A— это символ 65 (восьмеричный 101 )в ASCII и всех совместимых с ASCII -наборах символов (, которые включают большинство современные кодировки, за исключением EBCDIC, которые до сих пор используются в некоторых системах IBM ).

В

printf \\$(printf '%03o' $1)

Что и следовало написать:

printf "\\$(printf '%03o' "$1")"

поскольку расширение параметров (, например $1), или подстановка команд($(...))без кавычек — это оператор split+glob в Bourne -, подобный оболочкам, который здесь не нужен

  • printf '%03o' "$1"преобразует число в $1в 3-значное восьмеричное
  • printf "\\$(...)"добавляет это восьмеричное значение к\(\\внутри двойных кавычек, становится\)и передает его в printf, чтобы вывести соответствующее значение байта.

Обратите внимание, что это работает только в локалях, где кодировка представляет собой один байт на символ (, например iso8859-1), или в локалях с многобайтовой кодировкой -только для значений от 0 до 127.

В bash,

printf '%d\n' "'A"

печатает точку кода Unicode -символаA(или, по крайней мере, значение, возвращаемое mbtowc(), которое в системах GNU по крайней мере является точкой кода Unicode -).

Некоторые другие реализации (, включая автономную утилиту GNU printf), вместо этого возвращают значение первого байта символа.

Для символов ASCII, таких как A, и в системах на основе ASCII -это не имеет значения, но для других имеет значение. Например, греческий символ α(U+03B1 )кодируется как:

  • байт 225 в iso8859 -7 (стандартная греческая одиночная кодировка -байтовая кодировка)
  • байты 206 177 в UTF -8 (наиболее часто используемая кодировка Unicode в Unix -подобных системах)
  • байты 166 193 в GB18030 (официальная китайская кодировка Unicode ).

Bash printf '%d\n' "'α"всегда будет выводить945(0x03b1 в шестнадцатеричном формате ), что является кодовой точкой Unicode для αнезависимо от локали (, по крайней мере, в системах GNU ), но другие могут возвращать 225, 206 или 166 в зависимости от региона.

Из этого видно, что эти chrи ordявляются обратными друг другу только для символов ASCII (или значений от 0 до 127 ), или в локалях, использующих набор символов iso8859-1для всех символы (значения от 0 до 255 ).

Если ord()предназначен для возврата кодовой точки Unicode, то обратная (печать символа, соответствующего кодовой точке Unicode ), будет:

chr() {
  printf "\U$(printf %08X "$1")"
}

(предполагает bash4.3 или выше(\UXXXXXXXXбыл добавлен в 4.2, но не работал должным образом для символов от U+0080 до U+00FF до 4.3 )).

Затем в любой локали:

$ ord α
945
$ chr 945
α

Или для ord()вернуть значения байтов кодировки заданного символа (в текущей локали):

ord() {
  printf %s "$1" | od -An -vtu1
}

И для chr()для вывода этих байтов:

chr() {
  printf "$(printf '\\%o' "$@")"
}

Затем, например, в локали UTF -8:

$ ord α
 206 177
$ chr 206 177
α

(ваш ord αдал бы 945,ваш chrдаст мусор как для chr 945, так и для chr 206 177).

Или в локали, используяiso8859-7:

$ ord α
 225
$ chr 225
α

(ваш ord αдаст 945, хотя может дать 225, если printfзаменить на /usr/bin/printfв системе GNU ).

10
28.04.2021, 23:26

хр

printf \\$ (printf '%03o' $1)#Должно быть...printf "$(printf '\\%03o' "$1")"

Первый printfиспользует вывод второго для создания символа. Нам нужно работать в обратном направлении, чтобы расшифровать его.

Второй printfиспользуется для преобразования целого числа (из$1)в восьмеричное целое число (формата '%03o').

$ printf '%03o' 12
014
$ printf '%03o' 65
101
$ printf '%03o' 255
377

Затем этот результат объединяется с эквивалентом \(, его необходимо удвоить --или заключить в кавычки --, чтобы избежать его специального значения для оболочки ). Результирующая строка \101интерпретируется printf как восьмеричное значение байта. Но только до трех цифр(в большинстве реализаций оболочки printf ). Эта интерпретация только трех восьмеричных цифр связана с тем, что этот тип формата предназначен для использования в одиночных байтах 0 -255 (или 0 -377 в восьмеричном ). Таким образом, большинство реализаций printf преобразуют восьмеричные числа только в один байт . Если этот байт представляет символ ascii в локали, используемой консолью, этот символ будет распечатан.

$ printf \\101\\n
A
$ printf \\377\\n
�

Для печати символов (, а не байтов ), на которые влияет нужная нам локаль:

  • printf, способный генерировать многобайтовые символы в используемой локали, и
  • некоторая форма выражения того, что нам нужен символ вместо байта,

например, в bash (4.3+):

$ printf \\U263A\\n
☺

Обратите внимание, что printfможет печатать много цифр:

$ printf '%03o\n' 1495195076287004671
122777777777777777777

Но в качестве восьмеричного числа принимаются только первые три:

$ printf '\122777777777777777777'
R777777777777777777                     # Note the R in the front.

или

printf '%d' "'$1"

Строка data (not format )удаляет внешние кавычки, и результирующая строка начинается с '. Строки, начинающиеся с 'или ", являются специальными для printf. Для этих строк, если формат числовой ,значение первого символа печатается (в формате, заданном строкой числового формата):

$ printf '%d\n' '"A'      # decimal (doesn't expand quoted vars '"$var')
65
$ printf '%d\n' "'A"      # decimal
65
$ printf '%o\n' "'A"      # octal
101
$ printf '%x\n' "'A"      # Hexadecimal
41

Обратите внимание, что существуют некоторые различия в "'…"интерпретации того, что является первым символом среди реализаций (байта или символа, и если это байт, результат зависит от используемой локали ).

0
28.04.2021, 23:26

Теги

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