Digamos que exporté una variable:
foo=bar
export foo
Ahora, me gustaría desexportarlo. Es decir, si lo hago, sh -c 'echo "$foo"'
no debería hacerlo bar
. foo
no debería aparecer en sh -c
el entorno del todo.
sh -c
es simplemente un ejemplo, una manera fácil de mostrar la presencia de una variable. El comando podría ser cualquier cosa, puede ser algo cuyo comportamiento se ve afectado simplemente por la presencia de la variable en su entorno.
Yo puedo:
unset
la variable, y la pierdes- Elimínelo usando
env
para cada comando:env -u foo sh -c 'echo "$foo"'
- poco práctico si desea continuar usando el shell actual por un tiempo.
Idealmente, me gustaría mantener el valor de la variable, pero que no se muestre en absoluto en un proceso secundario, ni siquiera como una variable vacía.
Supongo que podría hacer:
otherfoo="$foo"; unset foo; foo="$otherfoo"; unset otherfoo
Esto corre el riesgo de pisotear otherfoo
, si ya existe.
¿Es esa la única forma? ¿Hay alguna forma estándar?
mktemp
si es que es lo suficientemente portátil, y desarmar el valor, y la fuente del archivo temporal para asignar la variable. Al menos se puede crear un archivo temporal con un nombre más o menos arbitrario en contraste con una variable de shell.sh -c
comando es simplemente un ejemplo. Tome cualquier comando dentro del cual no pueda desarmar una variable en su lugar, si lo desea.Respuestas:
No hay una forma estándar.
Puede evitar usar una variable temporal usando una función. La siguiente función se encarga de mantener las variables no establecidas y las variables vacías vacías. Sin embargo, no admite características que se encuentran en algunos shells, como variables de solo lectura o de tipo.
En ksh, bash y zsh, puede exportar una variable con
typeset +x foo
. Esto conserva propiedades especiales como los tipos, por lo que es preferible usarlo. Creo que todos los proyectiles que tienentypeset
incorporado tienentypeset +x
.fuente
${var+foo}
, evalúafoo
sivar
está configurado, incluso si está vacío, y nada de lo contrario.typeset +x
vsexport -n
para los shells que admiten el primero? ¿Esexport -n
más raro o no conserva algunas propiedades?export -n
otypeset +x
indiferentemente. En ksh o zsh, solo haytypeset +x
.EDIT: Para
bash
única, como se ha señalado en los comentarios:La
-n
opción paraexport
eliminar laexport
propiedad de cada nombre de pila. (Verhelp export
)Así que para
bash
, el comando que desea es:export -n foo
fuente
Escribí una función POSIX similar, pero esto no arriesga la ejecución de código arbitrario:
También manejará tantos argumentos como desee para proporcionarlo. Si un argumento es un nombre válido que de otro modo no está establecido, se ignora en silencio. Si un argumento es un nombre incorrecto, escribe en stderr y se detiene según corresponda, aunque cualquier nombre válido que precede a un inválido en su línea de comando aún se procesará.
Pensé en otra forma. Me gusta mucho mejor.
Bueno, ambos usan muchas de las mismas técnicas. Básicamente, si un shell var está desarmado, una referencia a él no se expandirá con una
+
expansión de parámetros. Pero si se establece, independientemente de su valor, una expansión de parámetros como:${parameter+word}
se expandirá aword
, y no al valor de la variable. Y así, las variables de shell se autoevalúan y sustituyen automáticamente en caso de éxito.También pueden fallar a sí mismos . En la función de la parte superior si un nombre mal se encuentra muevo
$1
en$2
y la licencia$1
nula debido a que el siguiente que hago es o bienreturn
el éxito si todos los argumentos han sido procesados y el bucle llega a su fin, o, si el arg no era válida, el shell ampliar la$2
en$1:?
que matará a una concha con guión y devolver una interrupción de un interactivo al escribirword
en stderr.En el segundo
getopts
hace las tareas. Y no asignará un nombre incorrecto, más bien escribirlo escribirá un mensaje de error estándar para stderr. Además, guarda el valor del argumento$OPTARG
si el argumento era el nombre de una variable establecida en primer lugar. Entonces, después de hacergetopts
todo lo que se necesita es la expansión deeval
un conjuntoOPTARG
en la asignación apropiada.fuente
export
un nombre extraño, no matará tu computadora.var=something; varname=var; export "$varname"
es perfectamente válido. lo mismo ocurreunset
con esto y con lo otro, pero en el momento en que el contenido de esa"$varname"
variable se vuelve loco, puede ser lamentable. y así es comobash
ocurrió toda la debacle de exportación de funciones.