Quiero ejecutar un script para simplemente cambiar el directorio de trabajo actual:
#!/bin/bash cd web/www/project
Pero, después de ejecutarlo, ¡el pwd actual permanece sin cambios! ¿Cómo puedo hacer eso?
Respuesta
Es un comportamiento esperado. El script se ejecuta en un subshell y no puede cambiar el directorio de trabajo del shell principal. Sus efectos se pierden cuando termina.
Para cambiar el directorio del shell actual de forma permanente, debe usar el comando source
, también llamado simplemente .
, que ejecuta un script en el entorno de shell actual en lugar de un sub shell.
Los siguientes comandos son idénticos:
. script
o
source script
Comentarios
Respuesta
Para tareas pequeñas como esta, en lugar de crear un script, cree un alias como este,
$ alias cdproj="cd /dir/web/www/proj"
Debe agregar esto a su .bashrc
archivo, si lo desea configurar para cada shell interactivo.
Ahora puede ejecutarlo como $ cdproj
.
Comentarios
- También puede hacer que el script repita los comandos que se ejecutarán y luego usar
eval `./script`
oeval $(./script)
para ejecutar esos comandos. Este es un enfoque común para los comandos que necesitan actualizar el entorno ‘ s de invocación. - Solo tenga mucho cuidado con lo que genera si va a ir el
eval
enfoque.
Responder
Use exec bash
al final
Un script bash opera en su entorno actual o en el de sus hijos, pero nunca en su entorno principal.
Sin embargo, esta pregunta a menudo se hace porque uno quiere quedarse en la fiesta en un directorio determinado después de la ejecución de un script bash de otro directorio.
Si este es el caso, simplemente ejecute una instancia secundaria de bash al final del script:
#!/usr/bin/env bash cd desired/directory exec bash
Esto crea una nueva subcapa. Escriba Ctrl + D o exit
para volver al primer shell donde se inició inicialmente el script.
Actualización
Al menos con las versiones más recientes de bash
, la exec
de la última línea ya no es necesaria. Además, se puede hacer que el script funcione con cualquier shell preferido utilizando la variable de entorno $SHELL
. Esto luego da:
#!/usr/bin/env bash cd desired/directory $SHELL
Comentarios
- Es mejor simplemente obtener el script, como en la respuesta aceptada : usar
exec
generalmente se considera el último recurso de un sinvergüenza .. 🙂 - este truco no ‘ t trabajar en debian 9 stretch.
- ¡Esta es la forma incorrecta de hacerlo!
- Dado que nadie ha detallado los problemas con esto (te estoy mirando, @Dennis): (1) Cada vez que ejecuta esto, crea un nuevo proceso de bash persistente. Hágalo diez o veinte veces en una sesión y tendrá de 11 a 21 procesos bash acumulados. Esto puede afectar el rendimiento y, si intenta terminar la sesión limpiamente escribiendo
exit
(o Ctrl + D), tendrá que hacerlo de 11 a 21 veces. (2) Otro inconveniente de usar un script ejecutable es que, si configura alguna opción de shell (por ejemplo,dotglob
oglobstar
) en su sesión de shell interactivo, los perderá, porque está iniciando un nuevo shell. - ¡Muy buena solución! ‘ he reescrito mi alias en bash_profile, así que ahora es un script almacenado en un archivo separado. Utilizo el script para ir a una carpeta temporal recién creada. Y ahora es aún más fácil tener una sesión de bash temporal. ¡SRP en acción! ¡Gracias!
Responder
Si bien hay respuestas que realizan la acción exacta que desea, un método más estándar para tal el propósito es crear un enlace simbólico:
ln -s ~/web/www/project proj #use full path to dir!
Entonces podría cd
al directorio usando el nombre proj
:
cd proj
Este método es más flexible porque puede acceder a los archivos utilizando el nombre corto sin cd
:
ls proj/ #note the endslash! vim proj/file.x
Responder
Depende de lo que «vamos a hacer, otra solución puede ser la creación de una función en lugar de un script.
Ejemplo:
Cree una función en un archivo, digamos /home/aidin/my-cd-script
:
function my-cd() { cd /to/my/path }
Luego inclúyalo en su bashrc
o zshrc
archivo:
# Somewhere in rc file source /home/aidin/my-cd-script
Ahora puede usarlo como un comando:
$ my-cd
Responder
Si cambia entre directorios lejanos en el sistema de archivos. Recomendaré autojump .
Respuesta
Para mí, el enfoque más conveniente y flexible fue una mezcla de un alias y un script:
crear un script con lógica arbitraria
Aquí creo un script que cambia a un directorio y activa el entorno de Python apropiado. La ubicación de los scripts es ejemplar en /path/to/workon_myproj.sh
.
#!/usr/bin/env bash cd $HOME/workspace/myproj source .venv/bin/activate
crear el alias que origina el script
alias workon_myproj="source /path/to/workon_myproj.sh"
Agregue la definición de alias en su archivo de inicio de shell apropiado, por ejemplo .profile
, .bashrc
o .zshrc
.
resultado
Ahora puede simplemente ejecutar workon_myproj
en un shell que obtendrá el contenido de su script en el directorio deseado.
extensibilidad
Podría eventualmente mejorar su script para tomar un argumento para que funcione con múltiples proyectos en un directorio de trabajo específico, o combinarlo con un git pull
para obtener los últimos cambios de inmediato y así en … todo lo relacionado con la placa de caldera que hace cuando continúa trabajando en un proyecto específico.
Respuesta
exec «parece hacer exactamente lo que deseo.
#!/bin/bash cd someplace exec bash ~/someplace
Comentarios
- Tenga cuidado con las cosas que parece ser lo que quieres. (¡Un caballo de madera gigante! ¡Justo lo que quería!) Cada vez que ejecuta esto, crea un proceso de bash nuevo y persistente. Hágalo diez o veinte veces en una sesión, y tendrá de 11 a 21 procesos bash apilados. Esto puede afectar el rendimiento y, si intenta terminar la sesión limpiamente escribiendo
exit
(o Ctrl + D), tendrá que hacerlo de 11 a 21 veces. - Definitivamente pude ver dónde eso sería un problema. Para mí, aunque ‘ lo uso una vez, hago el trabajo que necesito y luego salgo. Si ese ‘ es el único inconveniente, puede vivir con eso. Por otro lado, si hay una solución mejor, ‘ estoy dispuesto a verla.
- La respuesta de Aidin a esta pregunta , usando una función de shell, y la la respuesta de Sachin Divekar , usando un alias, son (IMO) mejores soluciones que usar un script. . PD Otro inconveniente de usar una secuencia de comandos es que, si configura alguna opción de shell (por ejemplo,
dotglob
oglobstar
), las perderá, porque estás iniciando un nuevo shell. … (Continuación) - (Continuación) … P.P.S. Me di cuenta de que, básicamente, estás reiterando la respuesta de Serge Stroobandt y dices «¿Por qué no hacer esto?» En Stack Exchange esperamos que las respuestas brinden nuevas ideas y / o información, y no solo discutan otras respuestas.
Responder
Esto combina la respuesta de Serge con una respuesta no relacionada de David . Cambia el directorio, y luego, en lugar de forzar un shell bash, lanza el shell predeterminado del usuario . Sin embargo, requiere tanto getent
como /etc/passwd
para detectar el shell predeterminado.
#!/usr/bin/env bash cd desired/directory USER_SHELL=$(getent passwd <USER> | cut -d : -f 7) $USER_SHELL
Por supuesto, esto todavía tiene la misma deficiencia de crear un shell anidado.
Respuesta
Puedes hacerlo usando una función o usando & & Los ejemplos siguientes instalan Zabbix y crean un archivo con una línea dentro.
Por ejemplo:
#!/bin/bash # Create Function: installZabbix(){ cd /usr/src/zabbix-4.2.4; ./configure --enable-agent; make install; cd /usr/src/; >file; echo "Hi, this is a file." >>file; } # Call the function: installZabbix
o:
#!/bin/bash cd /usr/src/zabbix-4.2.4 && ./configure --enable-agent && make install && cd /usr/src && >file && echo "Hi, this is a file." >>file
return
para escapar de un script generado de esta manera, noexit
; son como funciones de shell yexit
saldrá del shell que generó el script.source ./script
es lo mismo?.
ysource
son iguales en bash. 2. no ‘ No es necesario usar./
antes del nombre de archivo si ‘ s en el mismo directorio. Está bien ejecutar solo esto:. script