linux - bash script change working directory
¿Por qué no funciona "cd" en un script de shell? (29)
Estoy intentando escribir un pequeño script para cambiar el directorio actual a mi directorio de proyecto:
#!/bin/bash
cd /home/tree/projects/java
Guardé este archivo como proyecto, agregué permiso de ejecución con chmod
y lo copié en /usr/bin
. Cuando lo llamo por: proj
, no hace nada. ¿Qué estoy haciendo mal?
Usa exec bash
al final.
Un script de bash opera en su entorno actual o en el de sus hijos, pero nunca en su entorno padre.
Sin embargo, esta pregunta a menudo se hace porque uno quiere quedarse en un mensaje de bash en un directorio determinado después de la ejecución de un script de bash desde otro directorio.
Si este es el caso, simplemente ejecute una instancia de bash secundaria al final del script:
#!/bin/bash
cd /home/tree/projects/java
exec bash
Para hacer un script de bash que se cd a un directorio de selección:
Crear el archivo de script
#!/bin/sh # file : /scripts/cdjava # cd /home/askgelal/projects/java
Luego crea un alias en tu archivo de inicio.
#!/bin/sh # file /scripts/mastercode.sh # alias cdjava=''. /scripts/cdjava''
- Creé un archivo de inicio donde volco todos mis alias y funciones personalizadas.
- Luego obtengo este archivo en mi archivo .bashrc para configurarlo en cada inicio.
Por ejemplo, cree un archivo maestro de alias / funciones: /scripts/mastercode.sh
(Ponga el alias en este archivo.)
Luego al final de su archivo .bashrc :
source /scripts/mastercode.sh
Ahora es fácil de copiar a su directorio de Java, simplemente escriba cdjava y estará allí.
¡No estás haciendo nada malo! Ha cambiado el directorio, pero solo dentro de la subshell que ejecuta el script.
Puede ejecutar el script en su proceso actual con el comando "punto":
. proj
Pero preferiría la sugerencia de Greg de usar un alias en este caso simple.
Cuando activa un script de shell, ejecuta una nueva instancia de ese shell ( /bin/bash
). Por lo tanto, su script simplemente activa un shell, cambia el directorio y sale. Dicho de otra manera, cd
(y otros comandos similares) dentro de un script de shell no afectan ni tienen acceso al shell desde el que se iniciaron.
El cd
en su script funcionó técnicamente ya que cambió el directorio del shell que ejecutó el script, pero fue un proceso separado derivado de su shell interactivo.
Una forma compatible con Posix de resolver este problema es definir un procedimiento de shell en lugar de un script de comando invocado por el shell.
jhome () {
cd /home/tree/projects/java
}
Solo puede escribir esto o ponerlo en uno de los varios archivos de inicio de shell.
El cd
se realiza dentro del shell del script. Cuando finaliza el script, ese shell se cierra y, a continuación, queda en el directorio en el que estaba. "Fuente" del script, no lo ejecute. En lugar de:
./myscript.sh
hacer
. ./myscript.sh
(Observe el punto y el espacio antes del nombre del script).
En mi caso particular necesité demasiadas veces para cambiar el mismo directorio. Así que en mi .bashrc (uso ubuntu) he añadido el
1 -
$ nano ~. / bashrc
function switchp
{
cd /home/tree/projects/$1
}
2-
$ source ~ / .bashrc
3 -
$ switchp java
Directamente hará: cd / home / tree / projects / java
¡Espero que ayude!
En su archivo ~ / .bash_profile. agrega la siguiente función
move_me() {
cd ~/path/to/dest
}
Reinicie el terminal y puede escribir
move_me
y será movido a la carpeta de destino.
Esto debería hacer lo que quieras. Cambie al directorio de interés (desde dentro del script) y luego genere un nuevo shell bash.
#!/bin/bash
# saved as mov_dir.sh
cd ~/mt/v3/rt_linux-rt-tools/
bash
Si ejecuta esto, lo llevará al directorio de interés y cuando salga, lo llevará de regreso al lugar original.
root@intel-corei7-64:~# ./mov_dir.sh
root@intel-corei7-64:~/mt/v3/rt_linux-rt-tools# exit
root@intel-corei7-64:~#
Esto incluso lo llevará a regresar a su directorio original cuando salga ( CTRL + d )
La idea de Jeremy Ruten de usar un enlace simbólico provocó un pensamiento que no ha cruzado ninguna otra respuesta. Utilizar:
CDPATH=:$HOME/projects
El colon principal es importante; significa que si hay un directorio ''dir'' en el directorio actual, entonces '' cd dir
'' cambiará a eso, en lugar de saltar a otro lugar. Con el valor establecido como se muestra, puede hacer:
cd java
y, si no hay un subdirectorio llamado java en el directorio actual, entonces lo llevará directamente a $ HOME / projects / java: sin alias, sin scripts, sin ejecutables dudosos o comandos de puntos.
Mi $ HOME es / Usuarios / jleffler; mi $ CDPATH es:
:/Users/jleffler:/Users/jleffler/mail:/Users/jleffler/src:/Users/jleffler/src/perl:/Users/jleffler/src/sqltools:/Users/jleffler/lib:/Users/jleffler/doc:/Users/jleffler/work
Los scripts de shell se ejecutan dentro de una subshell, y cada subshell tiene su propio concepto de lo que es el directorio actual. El cd
tiene éxito, pero tan pronto como la subshell sale, estás de vuelta en la shell interactiva y nada cambia allí.
Una forma de evitar esto es usar un alias en su lugar:
alias proj="cd /home/tree/projects/java"
MIRANDO tiempo después, pero hice lo siguiente:
crear un archivo llamado caso
pega lo siguiente en el archivo:
#!/bin/sh
cd /home/"$1"
Guárdalo y luego:
chmod +x case
También creé un alias en mi .bashrc
:
alias disk=''cd /home/; . case''
ahora cuando escribo:
case 12345
Básicamente estoy escribiendo:
cd /home/12345
Puede escribir cualquier carpeta después de ''caso'':
case 12
case 15
case 17
que es como escribir:
cd /home/12
cd /home/15
cd /home/17
respectivamente
En mi caso, el camino es mucho más largo, estos chicos lo resumieron con la información anterior.
No necesita ningún script, solo configure la opción correcta y cree una variable de entorno.
shopt -s cdable_vars
en su ~/.bashrc
permite ~/.bashrc
el contenido de las variables de entorno.
Crear tal variable de entorno:
export myjava="/home/tree/projects/java"
y puedes usar:
cd myjava
Observe la discusión ¿Cómo configuro el directorio de trabajo del proceso padre?
Contiene algunas respuestas de hackers, por ejemplo, https://.com/a/2375174/755804 (cambiando el directorio del proceso principal a través de gdb, no hagas esto) y https://.com/a/51985735/755804 ( el comando tailcd
que inyecta cd dirname al flujo de entrada del proceso principal; bueno, idealmente debería ser una parte de bash en lugar de un hack)
Puede combinar los enfoques de alias y puntos de Adam & Greg para hacer algo que pueda ser más dinámico:
alias project=". project"
Ahora, ejecutar el alias del proyecto ejecutará la secuencia de comandos del proyecto en el shell actual en lugar de la subshell.
Puede crear una función como la siguiente en su .bash_profile
y funcionará sin problemas.
La siguiente función toma un parámetro opcional que es un proyecto. Por ejemplo, simplemente puede ejecutar
cdproj
o
cdproj project_name
Aquí está la definición de la función.
cdproj(){
dir=/Users/yourname/projects
if [ "$1" ]; then
cd "${dir}/${1}"
else
cd "${dir}"
fi
}
No te olvides de la fuente de tu .bash_profile
Puede ejecutar algunas líneas en la misma subshell si finaliza las líneas con barra invertida.
cd somedir; /
pwd
Puede utilizar el operador &&:
cd myDirectory && ls
Puedes combinar un alias y un script,
alias proj="cd /`/usr/bin/proj !*/`"
siempre que el script haga eco de la ruta de destino. Tenga en cuenta que esos son comillas invertidas alrededor del nombre del script
Por ejemplo, su script podría ser
#!/bin/bash
echo /home/askgelal/projects/java/$1
La ventaja de esta técnica es que la secuencia de comandos podría tomar cualquier número de parámetros de línea de comando y emitir diferentes destinos calculados por lógica posiblemente compleja.
Puedes hacer lo siguiente:
#!/bin/bash
cd /your/project/directory
# start another shell and replacing the current
exec /bin/bash
EDITAR: Esto también podría ser ''punteado'', para evitar la creación de shells subsiguientes.
Ejemplo:
. ./previous_script (with or without the first line)
Si bien el suministro de la secuencia de comandos que desea ejecutar es una solución, debe tener en cuenta que esta secuencia de comandos puede modificar directamente el entorno de su shell actual. Además ya no es posible pasar argumentos.
Otra forma de hacerlo es implementar su script como una función en bash.
function cdbm() {
cd whereever_you_want_to_go
echo "Arguments to the functions were $1, $2, ..."
}
Autojump utiliza esta técnica: http://github.com/joelthelion/autojump/wiki para proporcionarle los marcadores de directorio de shell de aprendizaje.
Si está utilizando fish como su cáscara, la mejor solución es crear una función. Como ejemplo, dada la pregunta original, podría copiar las 4 líneas a continuación y pegarlas en la línea de comando de su pez:
function proj
cd /home/tree/projects/java
end
funcsave proj
Esto creará la función y la guardará para usarla más tarde. Si su proyecto cambia, simplemente repita el proceso utilizando la nueva ruta.
Si lo prefiere, puede agregar manualmente el archivo de función haciendo lo siguiente:
nano ~/.config/fish/functions/proj.fish
y escriba el texto:
function proj
cd /home/tree/projects/java
end
y finalmente presione ctrl + x para salir e y seguido de regresar para guardar sus cambios.
( NOTA: el primer método de uso de funcsave crea el archivo proj.fish por usted ).
Solo cambia el directorio para el script en sí, mientras que su directorio actual permanece igual.
Es posible que desee utilizar un enlace simbólico en su lugar. Te permite crear un "acceso directo" a un archivo o directorio, por lo que solo deberías escribir algo como cd my-project
.
Tengo mi código para trabajar mediante el uso . <your file name>
. <your file name>
./<your file name>
dosis no funciona porque no cambia su directorio en el terminal, solo cambia el directorio específico de ese script.
Aqui esta mi programa
#!/bin/bash
echo "Taking you to eclipse''s workspace."
cd /Developer/Java/workspace
Aqui esta mi terminal
nova:~ Kael$
nova:~ Kael$ . workspace.sh
Taking you to eclipe''s workspace.
nova:workspace Kael$
Tengo un script bash simple llamado p para administrar el cambio de directorio en
github.com/godzilla/bash-stuff
simplemente coloque el script en su directorio bin local (/ usr / local / bin)
y pon
alias p=''. p''
en tu .bashrc
Usted puede utilizar .
para ejecutar un script en el entorno shell actual:
. script_name
o alternativamente, su source
alias más legible pero específica al shell:
source script_name
Esto evita la subshell, y permite que cualquier variable o componente (incluido cd
) afecte al shell actual en su lugar.
para navegar directorios rápidamente, hay $ CDPATH, cdargs y formas de generar alias automáticamente
http://jackndempsey.blogspot.com/2008/07/cdargs.html
http://muness.blogspot.com/2008/06/lazy-bash-cd-aliaes.html
https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-5827311.html
simplemente ejecute:
cd /home/xxx/yyy && command_you_want
Usando las funciones de perfil de Bash:
Una de las características del perfil de bash es almacenar funciones personalizadas que se pueden ejecutar en el terminal o en los scripts de bash de la misma manera que ejecuta las aplicaciones / comandos, esto también podría usarse como acceso directo para comandos largos.
Para hacer que su sistema sea eficiente, deberá copiar su función al final de varios archivos.
/home/user/.bashrc
/home/user/.bash_profile
/root/.bashrc
/root/.bash_profile
Puede sudo kwrite /home/user/.bashrc /home/user/.bash_profile /root/.bashrc /root/.bash_profile
para editar / crear esos archivos rápidamente
Ejemplo de Script
Haciendo atajo a cd ..
con cdd
cdd() {
cd ..
}
ls atajo
ll() {
ls -l -h
}
ls atajo
lll() {
ls -l -h -a
}
Cómo :
Copie su función al final de sus archivos y reinicie su terminal, luego puede ejecutar cdd
o cualquiera que sea la función que escribió