Здесь есть ряд понятий, которые распространены в мире безопасности.
Во-первых, мы всегда хотим, чтобы пользователи работали с «наименее необходимыми привилегиями». Идея, особенно в корпоративной среде (, я вернусь к этому чуть позже ), заключается в том, что мы хотим, чтобы люди имели разрешения, необходимые им для использования компьютера, но не более того. «Бизнес как обычно» (BAU )не требует изменения файлов в /etc; это исключительный случай.
Это ведет к следующей части; «повышение привилегий». Как только определено что-то за пределами BAU, мы хотим, чтобы пользователь знал, что он делает что-то более привилегированное. Поэтому используйте команду sudo
и по поводу -введите свой пароль, чтобы подтвердить, что вы знаете, что делаете. Этот повторный -ввод пароля важен, поскольку он означает, что пользователь сознательно одобряет это действие. Это не обязательно должен быть пароль; есть версии, которые могут потребовать двухфакторную аутентификацию, которая будет регистрировать нажатие клавиши и записывать сеанс для последующего воспроизведения...
Итак, теперь мы подошли к «предприятию» и рассмотрели уроки Windows XP Home Edition. При этом пользователь, которого вы создали при установке (или первой -загрузке для OEM ), автоматически имел права администратора. Ты всегда работал как админ. Это означало, что любая ваша ошибка может привести к удалению важных файлов. Или любая из ошибок (, например, в электронной почте, или рендеринге изображений, или... ), которые позволяли злоумышленнику выполнять действия автоматически, имели права администратора. Это одна из причин, почему в старых версиях Windows свирепствовали вирусы и вредоносное ПО.
Таким образом, разделение «BAU» и «привилегированных» действий распространяется за пределы предприятия и на дом, а также на единую -пользовательскую среду. Стоит отметить, что, начиная с Vista, даже в Windows есть концепция «вы пытаетесь сделать что-то привилегированное; повторно -введите свой пароль».
Резюме:sudo
— это просто способ переключения контекстов безопасности;от деятельности, которую вы могли бы разумно выполнять каждый день («прочитать электронную почту», «создать документ», «просматривать веб-страницы» )и прочее, что считается привилегированным («создать нового пользователя», «изменить конфигурация системы», «удалить файлы, принадлежащие другому пользователю»… ).
Для большинства домашних пользователей достаточно просто «повторно -введите свой пароль». Для предприятия все может стать намного сложнее; см.https://www.sweharris.org/post/2018-08-26-minimal-sudo/для примера некоторых проблем.
ИЗМЕНИТЬ ДЛЯ ДОБАВЛЕНИЯ:
Я также должен отметить, что в Unix также есть понятие «пользователь-администратор»; это «корневая» учетная запись. В корпоративной среде нам не нравятся люди, использующие это, потому что мы не знаем, использовали ли Том, Дик или Гарри учетную запись root для внесения изменений. sudo
— это способ, позволяющий людям повышать свои привилегии проверяемым наименее привилегированным способом. Том может запустить sudo cat
и прочитать любой файл, но не может перезагрузить машину; Дик и Гарри могут sudo reboot
перезагрузить машину, но не могут читать защищенные файлы.
Таким образом sudo
позволяет назначать минимальные привилегии, необходимые для выполнения роли . Что является ключевым требованием безопасности.
del(..|select(. == "null"))
При этом используется рекурсивный -оператор спуска..
иselect
функция для поиска всех местоположений в любом месте объекта со значениями, равными "null"
, и присваивается им del
. select
оценивает логическое выражение, чтобы решить, следует ли включать определенное значение или нет, в то время как ..
передает ему каждое отдельное значение в дереве, а del
принимает любое выражение, которое создает местоположения, что и делает это.(демо)
Вы можете использовать функцию path
, чтобы проверить, что она находит:
path(..|select(. == "null"))
и отладьте то, что, по его мнению, вы пытаетесь удалить в первую очередь. Выход представляет собой массив ключей, которым нужно рекурсивно следовать для достижения значения, поэтому последний элемент массива — это ключ, который фактически будет удален.
Вы также можете использовать назначение обновления -с |= empty
в jq 1.6 и выше (в более ранних версиях происходит сбой ). Вам может показаться, а может и нет, что эта:(..|select(. == "null")) |= empty
(демонстрация)удаляет те же ключи.
Если ваши значения верны null
s, а не строки "null"
, вы можете использовать встроенную функцию nulls
вместо всегоselect
:del(..|nulls)
.
Если ваши значения являются истинными нулями и вы используете jq 1.5(текущую версию во многих дистрибутивах ), вам нужно будет использовать recurse(.[]?; true)
вместо ..
. Это связано с тем, что нулевые значения специально исключены из ..
(, поскольку определяется как recurse
, определяется как recurse(.[]?)
, который определяется какrecurse(.[]?;. != null)
). Это поведение изменилось на (более полезное )описанное выше в 1.6, хотя документация не изменилась, что похоже на ошибку документации .
Предполагая, что вы знаете, что хотите проверить значения на 2-м уровне:
jq 'del(.[][] | select(. == "null"))' file
Это удаляет каждую пару значений ключа -на 2-м уровне сверху, где значением является литеральная строка null
.
Учитывая документ в вопросе, это дает ожидаемый результат.
Используя версию jq
более новую, чем 1.5, вы также можете просто обновить данные до битов, которые не имеют значения null
:
jq '.[][] |= select(. != "null")' file