Tengo un script que inserta algunas líneas en la parte inferior de mi archivo .bashrc
. ¿Hay alguna forma de obtenerlo .bashrc
desde el script para que estos cambios permanezcan una vez que el script haya finalizado? Aquí hay un MWE de un guión similar:
#!/bin/bash
echo "export MyDir='MyAnalysis'" >> ~/.bashrc
echo "alias llA='ll MyAnalysis'" >> ~/.bashrc
source ~/.bashrc
Cuando se ha ejecutado el script, ninguno de los MyDir
dos llA
está disponible a menos que el .bashrc
archivo se obtenga manualmente
Respuesta1
No directamente.
Su script se ejecuta en un proceso separado de su shell interactivo. Cualquier cambio que el shell del script realice en el entorno desaparecerá cuando ese shell salga.Un proceso hijo no puede alterar el entorno del padre.
Cosas que puedes hacer:
el script actualiza su .bashrc y no hace nada más: obtiene su bashrc si el script se completa correctamente
bash yourScript.bash && source .bashrc
el script actualiza .bashrc yhuellas dactilaresel comando fuente: asegúrese de que no imprima nada más. Luego realizas
eval
la ejecución del script.eval "$(bash yourScript.bash)"
el script actualiza el .bashrc ytambiénimprime lo que hace. Lo evalúas: este es el guión
#!/bin/bash exec > >(tee -a "$HOME/.bashrc") echo "export MyDir='MyAnalysis'" echo "alias llA='ll MyAnalysis'"
y lo ejecutas como
eval "$(bash yourScript.bash)"
no actualices elpadreshell, pero lanza un nuevo shell interactivo que leerá el bashrc
#!/bin/bash { echo "export MyDir='MyAnalysis'" echo "alias llA='ll MyAnalysis'" } >> ~/.bashrc exec bash -i
El shell principal no se actualiza.
Si convierte el código de actualización .bashrc en unfunción, funcionará como se esperaba porque las funciones se ejecutan en el shell actual (de forma predeterminada):
addMyAnalysis() {
echo "export MyDir='MyAnalysis'" >> ~/.bashrc
echo "alias llA='ll MyAnalysis'" >> ~/.bashrc
source ~/.bashrc
}
Una técnica alternativa: crear un directorio "conf" $HOME/.bash.d
. Escribe el archivo bash allí
# this is "~/.bash.d/some_file.bash"
export MyDir='MyAnalysis'
alias llA='ll MyAnalysis'
Y su .bashrc genera cualquier archivo bash en ese directorio:
if [[ -d ~/.bash.d ]]; then
shopt -s nullglob
for f in ~/.bash.d/*.bash; do
source "$f"
done
shopt -u nullglob
fi
Respuesta2
Como lo señaló @glenn-jackman, su abastecimiento ocurre en un subshell donde se ejecuta su script, y al final de su script regresa al shell principal donde no ocurrió ningún abastecimiento y tampoco .bashrc se ejecuta de nuevo: esta separación de padre y subcapa surge de consideraciones generales de seguridad.
Lo que estás buscando es exec bash
, pero no dentro de tu script, sino agrupado con él, es decir
bash your-script.sh && exec bash
esto se comportacomo siobtendrías y luego permanecerías en ese caparazón donde obtuviste. De hechoreemplazael shell actual con un nuevo shell, y este nuevo shell comienza, como cada shell (interactivo), con la ejecución de su .bashrc, ahora con sus cambios, y también lo hace cada nuevo shell/terminal que inicia.
Tenga en cuenta que si "ejecutara bash" en su script, reemplazaría el subshell donde se ejecuta su script, pero seguiría siendo un subshell.
Si su objetivo es una manipulación dinámica y temporal de .bashrc, debe considerar las sugerencias de @glenn-jackman para realizar los cambios en archivos separados que se pueden eliminar fácilmente en cualquier momento de su elección. Para eso también podrías tener una línea permanente.
[ -f ~/.bashrc-temporary-addons ] && source ~/.bashrc-temporary-addons
al final de su .bashrc y luego haga (! solamenteuno">" en la primera línea para tener un archivo nuevo)
echo "" > ~/.bashrc-temporary-addons
echo "export MyDir='MyAnalysis'" >> ~/.bashrc-temporary-addons
echo "alias llA='ll MyAnalysis'" >> ~/.bashrc-temporary-addons
y, en el punto que tú elijas, simplemente
rm ~/.bashrc-temporary-addons
(Debido a la prueba "-f", no habrá error si "~/.bashrc-temporary-addons" no existe).
Si sus manipulaciones .bashrc deben durar tanto como su sesión, es decir, hasta cerrar sesión (pero no reaparecer en el próximo inicio de sesión), entonces puede crear un .bash_logout
archivo para borrar archivos temporales en "bash.d/" o todo el contenido de "bash. d/", o "~/.bashrc-temporary-addons".