Un enfoque es anular export
y unset
Con funciones que hacen un seguimiento de sus variables.
Tenga en cuenta que para que esto funcione usted debe exportar variables como esta: export <variable>=<value>
.
Las dos funciones deben ser llamadas export
y unset
y mantenga una lista de sus variables en un archivo, que nombraré ~/.track$$
( $$
es el PID de tu shell actual):
export ()
{
if echo $@ | egrep -q '[^=]+=[^=]+' && builtin export "$@" && echo $- | grep -q i; then # [1]
touch ~/.track$$ # [2]
cp -fa ~/{.track$$,.track$$.bak} 2> /dev/null; # [3]
grep -v "^$(echo $@ | sed 's/\([^=]=\).\+/\1/')" < ~/.track$$.bak > ~/.track$$ 2> /dev/null; # [4]
echo $@ >> ~/.track$$; # [5]
fi
}
unset ()
{
if builtin unset $@ && echo $- | grep -q i; then # [1]
touch ~/.track$$ # [2]
cp -fa ~/{.track$$,.track$$.bak} 2> /dev/null; # [3]
egrep -v "^$@=" < ~/.track$$.bak > ~/.track$$ 2> /dev/null; # [4]
fi
}
Además, debe averiguar qué variables de entorno ha establecido. Un alias como este lo hará:
alias iset="cat ~/.track$$ 2>/dev/null"
Un alias como este:
alias ireset="rm ~/.track$$ >/dev/null 2>&1"
se puede utilizar para restablecer la lista.
Para mantener el número de ~/.track$$
archivos al mínimo podemos usar este comando de limpieza:
rm $(ls -d ~/.* | egrep 'track[0-9]+$|track[0-9]+\.bak$' | egrep -v $(ps -ef | grep bash | grep -v grep | awk '{print $2}' | tr '\n' '|' | sed 's/|$//')) > /dev/null 2>&1
¿Dónde deberíamos poner estas funciones, alias, etc?
Le recomendaría que agregue las funciones, los alias y el comando de limpieza al final de ~/.bashrc
, para que las subshells obtengan las funciones también. Dependiendo de tu distro y como /etc/profile
, /etc/bash.bashrc
y los amigos se ejecutan, puede definirlos demasiado pronto (en algunas distribuciones ~/.profile
fuentes ~/.bashrc
o al revés) por lo que puede que tenga que ajustarlo.
Luego cierre la sesión y vuelva a iniciar sesión.
Ahora si corres export <variable>=<value>
en tu sesión de bash la función export
:
[1] verifica si el parámetro está bien formado (esto es para evitar entradas falsas al escribir export MYVAR
, porque su valor de retorno es 0 y crearía una entrada en ~/.track$$
)
[1] entonces ejecuta builtin export <variable>=<value>
(esto establece la variable, independientemente de lo que suceda después)
[1] entonces se agita $-
para ver si se trata de una shell interactiva (ver esta respuesta Cuando ssh en una máquina de Ubuntu, qué tipo de shell estoy usando [enchufe desvergonzado]). De forma predeterminada, las subshells no heredan funciones, por lo que los scripts no se crean ~/.track$$
archivos. Si un script usa #!/bin/bash -i
, aunque, lo hará. Esto lo evitará.
[2] entonces toca ~/.track$$
para asegurarse de que existe y
[3] hace una copia de respaldo
[4] luego verifica si la variable ya existe, si ese es el caso, se elimina de ~/.track$$
[5] finalmente, agrega una línea a ~/.track$$
Del mismo modo, si escribe unset <variable>
y golpear Entrar la función unset
:
[1] ejecuta builtin unset <variable>
(esto elimina la variable, independientemente de lo que ocurra después)
[1] si unset
Fue exitoso lo comprueba, como en el export
función de arriba Si esto es un shell interactivo (ver esta respuesta Cuando ssh en una máquina de Ubuntu, qué tipo de shell estoy usando [enchufe desvergonzado]). Por defecto, las subshells no heredan funciones, por lo que los scripts no crean ~/.track$$
archivos. Si un script usa #!/bin/bash -i
, aunque, lo hará. Esto lo evitará.
[2] entonces toca ~/.track$$
para asegurarse de que existe y
[3] luego hace una copia de respaldo de ~/.track$$
[4] elimina la entrada variable de ~/.track$$
Cuál es el builtin
¿Qué palabra clave utilicé en ambas funciones? Ya que export
o unset
son shell builtins (es decir, comandos que vienen con el shell) que necesito usar builtin
, que es en sí mismo un comando incorporado (desde man bash
):
shell-builtin builtin [argumentos]
Ejecute el shell especificado, pasándole argumentos y devuelva su estado de salida. Esto es útil cuando se define una función cuyo nombre es el mismo que el de una shell incorporada, manteniendo la funcionalidad de la incorporada dentro de la función. El CD incorporado se redefine de esta manera. El estado de retorno es falso si shell-builtin no es un comando incorporado de shell.
El comando de limpieza enumera y filtra los activos ~/.track$$
archivos y elimina el resto.
Lo que obtienes con esta configuración:
Ya no es necesario usar guiones bajos. Simplemente usa el familiar export
comando (que ha sido anulado con una función) y funcionará.
Cada bash
sesión tiene su propio ~/.track$$
expediente. No colisiones entre conchas.
Como efecto secundario de lo anterior, las subshells no heredan las de los padres. ~/.track$$
Archivo, aunque heredan todas las variables de entorno.
Variables de entorno establecidas en archivos de origen ( . file
o source file
) se agregan a ~/.track$$
.
Las variables de entorno establecidas en una () subshell también se rastrean (incorrectamente), porque $$
se expande a la ID de proceso del shell actual, no a la subshell (ver man bash
).
Las variables se enumeran desde el primero hasta el último exportado.
Variables establecidas por .profile
y otros guiones que usted reasignar (incluso con el mismo valor) será listado por iset
. Por ejemplo, HOME
es usualmente establecido por .profile
. Si lo haces export HOME=/usr/local/bin:$HOME
y correr iset
ya verás HOME
listado
Y ahora algunos ejemplos:
Las variables exportadas se muestran con iset
:
$ export MYVAR1=0987654321; iset
MYVAR1=0987654321
Las variables redefinidas se tratan adecuadamente:
$ export MYVAR2="this is a string"; iset
MYVAR1=0987654321
MYVAR2=this is a string
$ export MYVAR2="this is a different string for the same variable"; iset
MYVAR1=0987654321
MYVAR2=this is a different string for the same variable
Entorno según env
partidos iset
salida:
$ env|grep MYVAR
MYVAR2=this is a different string for the same variable
MYVAR1=0987654321
Las variables de solo lectura no se agregan a ~/.track$$
:
$ export EUID=0; iset
-bash: EUID: readonly variable
MYVAR1=0987654321
Antiguos, los archivos de pista que ya no se utilizan se eliminan cuando ~/.bashrc
se ejecuta (por ejemplo, al crear una subshell):
$ ls -1 ~/.track*
.track11002
.track11002.bak
.track21774
.track21774.bak
.track2923
.track2923.bak
.track7382
.track7382.bak
.track8374
.track8374.bak
$ echo $$
2923
$ bash
<subshell>$ ls -1 ~/.track*
.track2923
.track2923.bak