Допустим, я экспортировал переменную:
foo=bar
export foo
Теперь я хотел бы отменить экспорт. То есть, если я это сделаю, sh -c 'echo "$foo"'
я не должен получить bar
. foo
вообще не должен появляться в sh -c
российской среде.
sh -c
это просто пример, простой способ показать наличие переменной. Командой может быть что угодно - это может быть что-то, на чье поведение влияет просто наличие переменной в ее окружении.
Я могу:
unset
переменная, и потерять ее- Удалите его, используя
env
для каждой команды:env -u foo sh -c 'echo "$foo"'
- нецелесообразно, если вы хотите продолжить использовать текущую оболочку на некоторое время.
В идеале я хотел бы сохранить значение переменной, но не показывать его вообще в дочернем процессе, даже в виде пустой переменной.
Я думаю, я мог бы сделать:
otherfoo="$foo"; unset foo; foo="$otherfoo"; unset otherfoo
Это может растоптать otherfoo
, если оно уже существует.
Это единственный способ? Есть ли стандартные способы?
mktemp
если что является портативным достаточно, и сбросить значение, и источник временный файл для присвоения переменной. По крайней мере временный файл может быть создан с более или менее произвольным именем в отличие от переменной оболочки.sh -c
является просто примером. Возьмите любую команду, в рамках которой вы не можете удалить переменную вместо нее, если хотите.Ответы:
Там нет стандартного способа.
Вы можете избежать использования временной переменной с помощью функции. Следующая функция заботится о том, чтобы неустановленные переменные оставались неустановленными, а пустые переменные оставались пустыми. Однако он не поддерживает функции, присутствующие в некоторых оболочках, такие как переменные только для чтения или типизированные переменные.
В ksh, bash и zsh вы можете удалить переменную с помощью
typeset +x foo
. Это сохраняет специальные свойства, такие как типы, поэтому предпочтительно использовать его. Я думаю, что все оболочки, которые имеютtypeset
встроенные, имеютtypeset +x
.источник
${var+foo}
, он оценивает,foo
еслиvar
установлено, даже если оно пустое, и ничего другого.typeset +x
сравнениюexport -n
для оболочек , которые делают поддержку бывшего? Является лиexport -n
реже, или же она не сохраняет некоторые свойства?export -n
илиtypeset +x
безразлично. В кш или зш есть толькоtypeset +x
.EDIT: Для
bash
только, как указано в комментариях:-n
Вариантexport
удаляетexport
свойство из каждого имени. (Смhelp export
.)Поэтому для
bash
, команда , которую вы хотите есть:export -n foo
источник
Я написал аналогичную функцию POSIX, но это не рискует выполнить произвольный код:
Он также будет обрабатывать столько аргументов, сколько вы пожелаете предоставить. Если аргумент является допустимым именем, которое в противном случае уже не задано, оно игнорируется. Если аргумент является неправильным именем, он записывает в stderr и останавливается соответствующим образом, хотя любое действительное имя, предшествующее недопустимому в его командной строке, все равно будет обработано.
Я думал о другом способе. Мне это нравится намного лучше.
Хорошо, оба из них используют много тех же самых методов. В основном, если оболочка var не установлена, ссылка на нее не будет расширяться с
+
расширением параметра. Но если он установлен - независимо от его значения - расширение параметра, подобное:${parameter+word}
будет расширяться доword
-, а не до значения переменной. И так переменные оболочки самопроверка и подстановка на успех.Они также могут потерпеть неудачу . В верхней функции, если найдено плохое имя, я вхожу
$1
в ноль$2
и оставляю$1
ноль, потому что следующее, что я делаю, это либоreturn
успех, если все аргументы были обработаны и цикл заканчивается, либо, если аргумент был недействительным, оболочка будет разверните объект,$2
в$1:?
котором будет уничтожена сценарий оболочки и верните прерывание интерактивному при записиword
в stderr.Во втором
getopts
делает задания. И это не будет назначать плохое имя - скорее напишите, это напишет стандартное сообщение об ошибке в stderr. Более того, он сохраняет значение аргумента в том$OPTARG
случае, если аргумент был именем переменной набора в первую очередь. Таким образом, после выполненияgetopts
все, что необходимо, это расширениеeval
набораOPTARG
в соответствующее назначение.источник
export
использовать странное имя, оно не убьет ваш компьютер.var=something; varname=var; export "$varname"
совершенно верно. То же самое относитсяunset
и к этому, и к другому, но в ту минуту, когда содержимое этой"$varname"
переменной сходит с ума, это может быть прискорбно. и это довольно, как всеbash
это произошло с экспортом всей функции.