Локальні змінні в zsh: що еквівалент bash "export -n" в zsh


10

Я намагаюся містити область змінної до оболонки, а не мати дітей, бачити її, в zsh. Наприклад, я набираю це в .zshrc:

GREP_OPTIONS=--color=always

Але якщо я запускаю скрипт оболонки із наступним:

#!/bin/bash
echo $GREP_OPTIONS

Вихід:

--color=always

хоча я хочу, щоб він був нульовим (сценарій оболонки вище взагалі не повинен бачити змінну GREP_OPTIONS).

По-баш, можна сказати:, export -n GREP_OPTIONS=--color=alwaysщо не дозволить цього статися. Як це зробити в zsh?


1
export -nпросто експортує експортовану змінну.
terdon

Відповіді:


11

exportв zsh є скороченим для typeset -gx, де атрибут gозначає "глобальний" (на відміну від локальної функції), а атрибут xозначає "експортується" (тобто в середовищі). Таким чином:

typeset +x GREP_OPTIONS

Це також працює в ksh та bash.

Якщо ви ніколи не експортуєте GREP_OPTIONSв першу чергу, вам не потрібно його експортувати.

Ви також можете скористатися непрямим, портативним способом: скидання змінної не експортує її. У ksh / bash / zsh це не працює, якщо змінна є лише для читання.

tmp=$GREP_OPTIONS
unset GREP_OPTIONS
GREP_OPTIONS=$tmp

Дивіться також env -u GREP_OPTIONS your-scriptдеякі envреалізації (будь-які оболонки). Або(unset GREP_OPTIONS; exec your-script)
Стефан Шазелас

Я спробував typeset + x, але це також не має значення. Як показано в моєму запитанні, щось експортує всі змінні, які я визначаю, навіть якщо я не включаю "експорт". Ще намагаюся з’ясувати, чому.
PonyEars

@redstreet Можливо, ви випадково встановили параметр export_all( -a)? Але навіть тоді typeset +x GREP_OPTIONSбуло б неекспортувати змінну. Якщо ви не можете знайти те, що не так, спробуйте виконати двійковий пошук: створіть резервну копію .zshrc, видаліть другу половину, подивіться, чи проблема все-таки виникає, а потім додайте третю чверть або скоротіть до першої чверті та повторіть.
Жил "ТАК - перестань бути злим"

@Gilles Спасибі, я знайшов це: zsh має "allexport" варіант, який у мене був у моєму .zshrc. "setopt noallexport" може тимчасово вимкнути його, якщо він допоможе комусь іншому. Я прийму вашу відповідь, оскільки вона наблизилася найближче.
PonyEars

Тепер у мене є інша проблема, яка ближче до проблеми, яку я намагаюся вирішити, тут: unix.stackexchange.com/questions/113645/…
PonyEars

6

Ви можете використовувати анонімну функцію, щоб забезпечити область для змінної. Від man zshall:

ANONYMOUS FUNCTIONS
       If no name is given for a function, it is `anonymous'  and  is  handled
       specially.  Either form of function definition may be used: a `()' with
       no preceding name, or a `function' with an immediately  following  open
       brace.  The function is executed immediately at the point of definition
       and is not stored  for  future  use.   The  function  name  is  set  to
       `(anon)'.

       Arguments to the function may be specified as words following the clos‐
       ing brace defining the function, hence if there are none  no  arguments
       (other than $0) are set.  This is a difference from the way other func‐
       tions are parsed: normal function definitions may be followed  by  cer‐
       tain  keywords  such  as `else' or `fi', which will be treated as argu
       ments to anonymous functions, so that a newline or semicolon is  needed
       to force keyword interpretation.

       Note also that the argument list of any enclosing script or function is
       hidden (as would be the case for any  other  function  called  at  this
       point).

       Redirections  may be applied to the anonymous function in the same man
       ner as to a current-shell structure enclosed in braces.  The  main  use
       of anonymous functions is to provide a scope for local variables.  This
       is particularly convenient in start-up files as these  do  not  provide
       their own local variable scope.

       For example,

              variable=outside
              function {
                local variable=inside
                print "I am $variable with arguments $*"
              } this and that
              print "I am $variable"

       outputs the following:

              I am inside with arguments this and that
              I am outside

       Note  that  function definitions with arguments that expand to nothing,
       for example `name=; function $name { ... }', are not treated as  anony‐
       mous  functions.   Instead, they are treated as normal function defini‐
       tions where the definition is silently discarded.

Але крім цього - якщо ви взагалі не використовуєте exportсвою .zshrcзмінну, вона повинна бути видимою лише у вашому поточному інтерактивному сеансі, і вона не повинна експортуватися до підпакетів.

Як terdon пояснив у своєму коментарі: export -nв bashтільки викликає властивість «експорт» , щоб видалити з змінної, тому використання export -n GREP_OPTIONS=--color=alwaysеквівалентно не використовуючи експорт взагалі - GREP_OPTIONS=--color=always.

Іншими словами, щоб отримати бажану поведінку, просто не використовуйте export. Натомість у своєму .zshrc, ви повинні мати

GREP_OPTIONS=--color=always

Це дозволить зробити змінну доступною для всіх запущених оболонок (інтерактивних, невхідних), як і ви хочете, але це не буде експортовано до дочірних оболонок.


Просто я маю GREP_OPTIONS = - color = завжди "- це те, що я роблю, як показано в моєму запитанні. Щось ще в zsh викликає автоматичне експортування всіх моїх змінних. Все ж намагаюся з'ясувати, що це таке
PonyEars
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.