Почему TR не может читать из/dev/urandom на OSX?

Можно передать zypper --auto-agree-with-licenses флаг. От OpenSUSE wiki:

Это - специальная опция для установки, удалите и обновите команды. При помощи этого пользователь объявляет, что соглашается с условиями лицензий, которые установит команда, и застежка-молния автоматически скажет 'да' подсказке подтверждения лицензии. Это полезно для людей, устанавливающих тот же набор пакетов на нескольких машинах (автоматизированным процессом), и прочитало все лицензии прежде.

37
14.08.2012, 01:38
6 ответов

На основе сообщения об ошибке, что Вы добираетесь, я не думаю, что/dev/urandom является проблемой. Если бы это было, то я ожидал бы ошибку как "никакой такой файл или каталог".

Я искал сообщение об ошибке, Вы получили и нашли это, которое кажется, что могло бы относиться к Вашей проблеме: http://nerdbynature.de/s9y/2010/04/11/tr-Illegal-byte-sequence

В основном укажите локаль путем предварительного ожидания tr команда с LC_CTYPE=C:

LC_CTYPE=C tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+= < /dev/urandom | head -c 32 | xargs
51
27.01.2020, 19:36
  • 1
    Спасибо, которое действительно добилось цели. Любая идея, почему я не могу найти urandom или random? Они - специальные волшебные "файлы", которые не существуют в фактической файловой системе? (Также я предложил, чтобы редактирование помогло смягчить гниль ссылки) –  Kirk Woll 13.08.2012, 21:53
  • 2
    я верю locate непосредственно не ищет Вашу файловую систему, а скорее ищет Ваш запрос с помощью предварительно созданной базы данных. Эта база данных, скорее всего, настроена для игнорирования/dev/и других 'специальных' файловых систем. достаточно ярмарка –  lk- 13.08.2012, 22:01
  • 3
    , но я не вижу его, когда я смотрю непосредственно в /dev. Пойди разберись. Но еще раз спасибо за справку. –  Kirk Woll 13.08.2012, 22:04
  • 4
    , кажется, не работает над 10,9; все еще сбои с тем же сообщением об ошибке. LC_ALL=C добивается цели tho. –  Erik Kaplun 24.03.2015, 13:31
  • 5
    Измените ту ссылку на nerdbynature.de/s9y/2010/04/11/tr-Illegal-byte-sequence как в настоящее время, она указывает на новую страницу блога, не содержащую tr информация. –  Jeroen Wiert Pluimers 03.05.2017, 19:16

Согласно странице справочника,/dev/random, вероятно, будет достаточным для Ваших потребностей. Возможно, Apple прекратила создавать/dev/urandom, потому что это является ненужным?

0
27.01.2020, 19:36
  • 1
    я не имею /dev/random также. версия 4.8.3 –  Kirk Woll 13.08.2012, 21:23
  • 2
    MacOSX должен иметь и/dev/random и/dev/urandom. Возможно, Apple больше больше не включает те специальные файлы? Или возможно это только там при установке XCode? –  jsbillings 13.08.2012, 21:36
  • 3
    FWIW, оба устройства присутствуют на моей Lion-upgraded-to-Mountain рабочей станции Льва. Я полагаю, что это присутствовало на Льве, также. Узлы отличаются также (13,0 по сравнению с 13,1) –  mrb 13.08.2012, 21:41

Ваш tr попытки интерпретировать его вход как текст в кодировке UTF-8. Таким образом, это будет жаловаться и прерываться на первую последовательность байта, которая не является допустимым UTF-8. Добавление префикса tr с LC_ALL=C или LC_CTYPE=C экспортирует ту переменную в среду tr, таким образом изменяя его идею локального набора символов к стандарту C, т.е. все - просто последовательность непрозрачных байтов.

Между прочим, последовательность \)-+ в Вашей намеренной команде? Это включает * также, который Вы уже включали, но не включаете - самостоятельно, поскольку Вы, возможно, предназначили. Лучше записать один из них вместо этого:

LC_ALL=C tr -dc 'A-Za-z0-9_!@#$%^&*()\-+=' < /dev/urandom
LC_CTYPE=C tr -dc A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)\\-+= < /dev/urandom
11
27.01.2020, 19:36

Как указывали другие, ваша проблема не в том, что / dev / urandom отсутствует, а в том, как tr работает в ОС X. Вместо того, чтобы возиться с varialbes окружения, используйте perl вместо tr :

perl -pe 'binmode(STDIN, ":bytes"); tr/A-Za-z0-9_\!\@\#\$\%\^\&\*\(\)-+=//dc;' < /dev/urandom | head -c 32; echo

Это дает преимущество переносимости между OS X, Redhat и Ubuntu.

(Я также удалил канал к xargs , заменив witch echo , чтобы получить новую строку в конце вывода.)

6
27.01.2020, 19:36

Во-первых, вы намеревались включить - или * в список допустимых символов? Параметр tr включает последовательность ) - + , что означает «диапазон байтов, начинающийся с ) и заканчивающийся на + , то есть на самом деле ) * + .

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

Эта конкретная версия проблемы немного необычен тем, что использует 76 различных символов; большинству просто нужны буквенно-цифровые, поэтому, если вас устраивают всего 64 символа, то использование утилиты base64 минимизирует потребление пула энтропии (обратите внимание, что 24 составляет 6/8 из 32):

head -c24 < /dev/random | base64
2
27.01.2020, 19:36

Кодировка символов вашей локали (которую вы можете узнать с помощью charmap локали) представляет собой мультибайт на символ.

В настоящее время наиболее распространенной является UTF-8, в которой символы могут быть закодированы от 1 до 4 байтов. Не все последовательности байтов образуют допустимые символы в UTF-8. Каждый символ, отличный от ASCII, в UTF-8 начинается с одного байта, в котором установлены два старших бита, и сообщает, сколько байтов с установленными старшими (но не вторыми старшими) битами следуют.

/dev/urandom содержит случайный поток байтов. tr транслитерирует символы, поэтому эти байты необходимо декодировать как символы. Все эти символы ASCII в вашем диапазоне закодированы одним символом в UTF-8, но tr по-прежнему необходимо декодировать все символы. Существуют, например, другие многобайтовые кодировки, в которых некоторые символы, отличные от A, содержат байт 0x41 (код для A).

Поскольку этот случайный поток байтов должен содержать недопустимые последовательности (например, байт 0x80 сам по себе является недопустимым в UTF-8, поскольку символ, отличный от ASCII, должен начинаться с байта, превышающего 0xc1 (0xc0 и 0xc1 находятся в нет символа UTF-8)), поэтому tr возвращается с ошибкой, когда это происходит.

Здесь вы хотите рассмотреть этот поток байтов как символы в кодировке, в которой один байт на символ. Что бы вы ни выбрали, это не важно, так как все эти символы в вашем диапазоне (при условии, что под AZ вы имели в виду ABCDEFGHIJKLMNOPQRSTUVWXYZ, а не такие вещи, как Ý, Ê) являются частью переносимого набора символов, поэтому будьте кодируется одинаково во всех кодировках, поддерживаемых вашей системой.

Для этого вы должны установить переменную локализации LC_CTYPE, которая определяет, какая кодировка используется и что такое пустой, альфа символ классы содержат. Но для определения диапазона от A до Z вам также потребуется установить переменную LC_COLLATE (ту, которая определяет порядок строк).

Локаль C, также известная как POSIX, гарантирует, что символы являются однобайтовыми, а A-Z — ABCDEFGHIJKLMNOPQRSTUVWXYZ. Вы можете сделать:

 LC_CTYPE=C LC_COLLATE=C tr -dc 'A-Za-z0-9_!@#$%^&*()+=-'

(здесь перемещение - в конец, иначе )-+ будет взято как диапазон, например AZ)

Но обратите внимание, что переменная LC_ALL переопределяет все остальные переменные LC_* и LANG.Таким образом, если LC_ALL уже определено, вышеизложенное не будет иметь никакого эффекта. Поэтому вместо этого вы можете просто сделать:

 LC_ALL=C tr -dc 'A-Za-z0-9_!@#$%^&*()+=-'

Это повлияет на другие вещи, такие как язык сообщений об ошибках, но в любом случае изменение LC_CTYPE уже могло быть проблемой для сообщений об ошибках (например, нет способа выразить сообщения об ошибках на русском или японском языках). в кодировке локали C).

1
27.01.2020, 19:36

Теги

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