для создания цветового профиля в Ubuntu 20.04 требуется аутентификация

Обработка переменных и область видимости в оболочке и особенно bashмогут быть очень неясными и неинтуитивными (и иногда содержать ошибки ).

kshимел typesetдля аналогичной функции. ksh, zsh, yashимеют typeset. bashимеет typesetкак псевдоним declareдля совместимости с ksh, zshимеет declareкак псевдоним typesetдля совместимости с bash. Большинство оболочек имеют export, readonlyи local, которые реализуют часть того, что делает typeset.

Одной из причин, почему bashавторы выбрали declareвместо typeset, может быть то, что typesetне только устанавливает тип, но также объявляет переменную :вводит ее в заданная область, возможно, с типом, атрибутами и/или значением.

В bashпеременные могут быть:

  • неизвестно (например, когда они никогда не устанавливались и не объявлялись)
  • объявлено (послеdeclare)
  • установите (при задании значения, возможно, пустого ).

Они могут быть разных типов:

  • скаляр
  • массив
  • ассоциативный массив

и иметь несколько атрибутов:

  • целое число
  • экспортировано
  • только для чтения
  • все нижний -/верхний -регистр
  • именованные ссылки

(хотя различие между типом и атрибутом может быть довольно размытым ).

Не все комбинации типов и атрибутов поддерживаются или эффективны.

Теперь declareобъявляет переменную в текущей области. bash, несмотря на то, что он реализует динамическую область видимости, внешняя -область видимости обрабатывается особым образом. Он называет это глобальной областью .

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

Когда вы выполняете declare varвнутри функции и при условии, что та же переменная не была объявлена ​​в той же области видимости, она объявляет новую новую переменную, которая изначально не установлена ​​и скрывает потенциальную varпеременную, которая должна была присутствовать в родительской области (вызывающей функции ).

Это динамическая область видимости, реализованная через своего рода стек. Когда функция завершается, статус, тип, атрибуты и значение переменной, какими они были при вызове функции, восстанавливаются (и извлекаются из стека ).

Однако вне любой функции (в глобальной области видимости ), declareобъявляет переменную, но не инициализирует ее как неустановленную, если она была установлена ​​до (так же, как при использовании declarea второй раз в той же области действия функции ). Если указан тип, значение переменной может быть преобразовано, хотя разрешены не все пути преобразования (, только скалярное преобразование в массив/хэш ), а атрибуты могут быть добавлены или удалены.

В bashфункция declare -gвоздействует на переменную в нижней части стека во внешней -самой ("глобальной" )области видимости.

declare -gбыл вдохновлен ksh93typeset -g. Но ksh93реализует статическую область видимости, где глобальная область видимости отличается и отделена от области видимости каждой функции. Делать то же самое с динамической областью видимости не имеет большого смысла. Во всех других оболочках, которые имеют typeset -g(mksh, zsh, yash), typeset -g, используется для изменения некоторого атрибута переменной без создания нового локального экземпляра.

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

Например:

integer() { typeset -gi "$1"; }

Чтобы сделать переменную целочисленной, используйте mksh/ yash/ zsh. В bashон работает только с переменными, которые не были объявлены локальными вызывающим кодом:

$ bash -c 'f() { declare a; integer a; a=1+1; echo "$a"; }; integer() { typeset -gi "$1"; }; f'
1+1
$ bash -c 'f() { integer a; a=1+1; echo "$a"; }; integer() { typeset -gi "$1"; }; f'
2

Обратите внимание, что export varне является ни typeset -x var, ни typeset -gx var. Он добавляет атрибут exportбез объявления новой переменной, если переменная уже существует. То же самое для readonlyпротив typeset -r.

Также обратите внимание, что unsetв bashотменяет установку переменной только в том случае, если она была объявлена ​​в текущей области видимости (оставляет ее объявленной, за исключением глобальной области видимости; он удаляет атрибуты и значения, и переменная больше не является массивом или хэшем; также обратите внимание, что в namerefs сбрасывается указанная переменная ). В противном случае он просто извлекает один переменный слой из стека, упомянутого выше. В bash5.0 или выше это можно исправить, установив параметр localvar_unset.

Подводя итоги:

 declare var

При вызове в функции и если varне было объявлено ранее в той же функции, объявляет переменную типа скалярная без атрибутов, которая изначально не установлена.

При вызове вне какой-либо функции или если varуже было объявлено в той же функции, это не имеет никакого эффекта, поскольку мы не указываем никакого нового типа или атрибута.

declare -g var

Где бы он ни вызывался, он объявляет varво внешней -самой ("глобальной" )области :делает его объявленным типа скалярного ], без атрибута, без значения, если он был ранее неизвестен в этой области (, которая по всем намерениям и целям аналогична неизвестной переменной, за исключением того, что она будет отображаться в выходных данныхtypeset -p)или ничего не делать в противном случае.

В любом случае,вы не сможете получить доступ к этой переменной в контексте, в котором вы выполняете эту команду:

f() { local a; g; }; g() { typeset -g a=123; echo "$a"; }; f

ничего не выводит.

1
16.10.2020, 08:56
1 ответ

Первый вход в CLI, нажмите ctrl+alt+f1или f2, затем войдите в систему под своим пользователем, затем попробуйте выполнить следующие действия:

нашел эту ошибку здесь:

https://bugzilla.redhat.com/show_bug.cgi?id=1149893

В частности, сюда необходимо поместить файл.rule,

/etc/polkit-1/rules.d/

(добавьте имя файла и просто дайте расширение.rules)

приведите ниже правила:

polkit.addRule(function(action, subject) {
   if ((action.id == "org.freedesktop.color-manager.create-device" ||
        action.id == "org.freedesktop.color-manager.create-profile" ||
        action.id == "org.freedesktop.color-manager.delete-device" ||
        action.id == "org.freedesktop.color-manager.delete-profile" ||
        action.id == "org.freedesktop.color-manager.modify-device" ||
        action.id == "org.freedesktop.color-manager.modify-profile") &&
       subject.isInGroup("username")) {
      return polkit.Result.YES;
   }
});

Затем вам нужно заменить слово «имя пользователя» на группу вашего пользователя.

1
18.03.2021, 22:57

Теги

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