Почему я не могу определить только для чтения переменную с именем path в zsh?

Решение, часть 1: Настройте kbd

Debian использует kbd , найдите BLANK_TIME в / etc / kbd / config :

# screen blanking timeout.  monitor remains on, but the screen is cleared to
# range: 0-60 min (0==never)  kernels I've looked at default to 10 minutes.
# (see linux/drivers/char/console.c)
BLANK_TIME=30

Изменение BLANK_TIME = 0 отключит гашение, см. Изменение поведения гашения экрана консоли Linux .

Проблема: ошибка в Jessie

Если это не сработает, возможно, вы столкнулись с ошибкой № 771161 / ошибкой № 750631 в Jessie.

Решение, часть 2: обходной путь для systemd

Отредактируйте /etc/init.d/kbd и измените строку 222 с

setterm $setterm_args

на

TERM=linux setterm > /dev/tty1 $setterm_args

. Технические подробности можно найти в отчете об ошибке выше.

5
26.11.2017, 17:27
1 ответ

TL;DR не используют повторно «специальные встроенные параметры», такие как path, потому что они особенные.Или согласно Списку рассылки можно использовать флаг -h:

% () { local -hr path=42; echo $path }
42
% 

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

Копаться дальше следует (, но я совершенно пропустил -hпрятки...)

% print ${(t)path}
array-special

Это функция свойства (? ошибка? )специальных переменных, но не подобных переменных, связанных пользователем:

% () { typeset -r PATH=/blah; echo $PATH }
(anon): read-only variable: PATH
% typeset -Tar FOO=bar foo
% print $foo
bar
% print ${(t)foo}
array-readonly-tag_local
% () { local -r foo=blah; echo $foo }
blah

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

% for p in $parameters[(I)*]; do print $p $parameters[$p]; done | grep array-
cdpath array-special
...
% () { local -r cdpath=42 }
(anon): read-only variable: cdpath

Таким образом, некоторые переменные, как в Скотный двор , более особенные, чем другие. Это сообщение об ошибке приходит из разных мест в Src/params.c, которые, если они изменены для печати, какое сообщение является конкретным сообщением, которое мы компилируем, что zshнаходим:

% () { local -r path }
% () { local -r path=foo }
(anon): read-only variable (setarrvalue): path

Является довольно общим кодом

/**/
mod_export void
setarrvalue(Value v, char **val)
{
    if (unset(EXECOPT))
        return;
    if (v->pm->node.flags & PM_READONLY) {
        zerr("read-only variable (setarrvalue): %s", v->pm->node.nam);
        freearray(val);
        return;
    }

Это показывает, что проблема возникает в другом месте; не -специальные переменные, несомненно, не имеют PM_READONLYустановки, в то время как специальные переменные, которые не работают, имеют. Следующим очевидным местом для поиска является код local, который имеет множество имен(typesetexport... ). Все это встроенные функции, поэтому их можно найти в глубинах Src/builtin.c

.
% grep BUILTIN Src/builtin.c | grep local
    BUILTIN("local", BINF_PLUSOPTS | BINF_MAGICEQUALS | BINF_PSPECIAL | BINF_ASSIGN, (HandlerFunc)bin_typeset, 0, -1, 0, "AE:%F:%HL:%R:%TUZ:%ahi:%lp:%rtux", NULL),

Все они вызывают bin_typesetс различными установленными флагами, поэтому давайте изучим исходный код этой функции... ругань в комментариях, проверьте. Отмечает, что все сложно, проверьте. На самом деле ничего не выскакивает, хотя кроличья нора (для случая, когда параметр «рассматривать аргументы как шаблоны» -mустановлен , а не , что имеет место здесь ), по-видимому, приводит к typeset_single] функция...

Существует некоторый код для POSIXBUILTINS, связанный с readonly, но он отключен в моих тестовых оболочках

% print $options[POSIXBUILTINS]
off

так что я проигнорирую этот код (надеюсь. Могло ли это быть логовом шогготов, а не просто кроличьей норой? ). Тем временем!Некоторые отладки указывают на то, что флаг PM_READONLYвключается для pathследующей строкой

    /*
     * The remaining on/off flags should be harmless to use,
     * because we've checked for unpleasant surprises above.
     */
    pm->node.flags = (PM_TYPE(pm->node.flags) | on | PM_SPECIAL) & ~off;

Которая, в свою очередь, исходит из переменной on, которая, в свою очередь, уже включена при входе в функцию typeset_single, вздох, так что вернемся к bin_typesetмы идем... ладно, в основном есть TYPESET_OPTSTR, которая каким-то образом через некоторые макросы по умолчанию включается PM_READONLY; когда вместо этого пользовательская переменная -проходит через этот путь кода, PM_READONLYотключается, и все хорошо.

Можно ли изменить это так, чтобы специальные переменные, такие как path, можно было сделать доступными только для чтения, это вопрос к разработчику ZSH (попробовать список рассылки рабочих zsh -? )в противном случае пока не возитесь со специальными переменными.

6
27.01.2020, 20:38

Теги

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