No puedo decir cuántas veces he deseado un comando que cree un directorio y se mueva a ese directorio. Básicamente, me gustaría el equivalente de lo siguiente:
mkdir -p /arbitrarily/long/path; cd /arbitrarily/long/path
pero solo tener que escribir /arbitrarily/long/path
una vez, algo como:
mk-cd /arbitrarily/long/path
Intenté crear un script para hacer esto, pero solo cambia el directorio dentro del script. Me gustaría que el directorio en el shell también haya cambiado.
#!/bin/bash
mkdir $1
cd $1
export PWD=$PWD
¿Cómo podría hacer que esto funcione?
cd
, elegiste un caso especial desde el principio. : Dcd
(regrese al directorio anterior usandocd -
, usepushd
ypopd
para mantener una "pila" de directorios): superuser.com/questions/324512/…mkdir -p /very/long/path
, luego usarcd
, espacio, y luego presionar Alt +.
para repetir el último argumento, es decir, el nombre del directorio.mkdir -p /very/long/path; cd !#:2
. La cadena!#:2
se expandirá al argumento nr. 2 (es decir, el tercer argumento/very/long/path
, ya que el conteo comienza con cero).!$
. Uso este truco en particular todo el tiempo, aunque hay mucho más que puedes hacer con la expansión del historial .Respuestas:
La forma más simple es usar una función de shell:
Colóquelo en su
.bashrc
archivo para que esté disponible para usted al igual que otro comando de shell.La razón por la que no funciona como una secuencia de comandos externa es
cd
cambiar el directorio actual de la secuencia de comandos en ejecución, pero no afecta a la llamada. Esto es por diseño! Cada proceso tiene su propio directorio de trabajo que es heredado por sus hijos, pero no es posible lo contrario.A menos que parte de una tubería, se ejecute en segundo plano o explícitamente en una subshell, una función de shell no se ejecuta en un proceso separado sino en el mismo, al igual que si el comando se ha originado. El shell del directorio actual puede ser cambiado por una función.
El
&&
utilizado aquí para separar ambos comandos utilizados significa que, si el primer comando tiene éxito (mkdir
), ejecute el segundo (cd
). En consecuencia, simkdir
no puede crear el directorio solicitado, no tiene sentido intentar entrar en él. Se imprime un mensaje de errormkdir
y ya está.La
-p
opción utilizada conmkdir
está allí para indicarle a esta utilidad que cree cualquier directorio faltante que sea parte de la ruta completa del nombre del directorio pasado como argumento. Un efecto secundario es que si solicita crear un directorio ya existente, lamkcd
función no fallará y terminará en ese directorio. Eso podría considerarse un problema o una característica. En el primer caso, la función se puede modificar, por ejemplo, de esa manera que simplemente advierte al usuario:Sin la
-p
opción, el comportamiento de la función inicial habría sido muy diferente.Si el directorio que contiene el directorio para crear aún no existe,
mkdir
falla y también lo hace la función.Si el directorio que se creará ya existe,
mkdir
falla también ycd
no se llama.Finalmente, tenga en cuenta que la configuración / exportación no
PWD
tiene sentido, ya que el shell ya lo hace internamente.Editar: agregué la
--
opción a ambos comandos para que la función permita un nombre de directorio que comience con un guión.fuente
~/.bashrc
uno de los otros scripts de inicialización.alias mk-cd 'mkdir -p \!:1; cd \!:1'
sin una función? ¿O tal vez debería comenzar a pensar en las funciones de bash más como alias extendidos?csh
mecanismo de aprobación de argumentos no se implementa con alias de estilo bourne. De hecho, las funciones son el camino a seguir, ya que son mucho más flexibles.bar
). Otra opción sería usarhistory 1
, como enalias mk-cd='args="$(history 1)" && args="${args#*mk-cd\ }" && mkdir -p "$args" && cd'
- esto funciona bien para el ejemplo del interlocutor, pero no es una solución general, ya que cualquier otro comando en la misma línea (por ejemplo, canalizar la salida) hará que falle.Me gustaría agregar una solución alternativa.
La secuencia de comandos se trabajará si se invoca con el
.
osource
comando:Si haces esto,
export
el script no es necesario. Puede omitir escribir.
usandoalias
:La razón por la que esto funciona es que un script normalmente se ejecuta en un sub-shell, por lo que su entorno se pierde al finalizar, pero el comando
.
(osource
) lo obliga a ejecutarse en el shell actual.Esta técnica puede ser útil para secuencias de comandos que son demasiado complejas para una función o que están en desarrollo y se editan con frecuencia: una vez que
alias
se ha ingresado.bash_aliases
, puede editar el script a voluntad sin reiniciarlo.Tenga en cuenta lo siguiente: -
Si escribe un script que debe llamarse con el comando
.
/source
, hay dos formas de asegurarse de esto:Por alguna razón, un script invocado con
.
/source
no necesita ser ejecutable, así que simplemente elimine este permiso y el script no se encontrará en "$ PATH" o dará un error de permiso si se invoca con una ruta explícita.Alternativamente, el siguiente truco se puede usar al comienzo del guión:
Esto funciona porque en un sub-shell
bind
emite una advertencia, aunque no hay estado de error: porread
lo tanto, se utiliza para dar un error en ninguna entrada.fuente
.
. Lo he hecho. .bashrc
innumerables veces, pero no sabía qué hace exactamente.
. ¿Es similar aexport
?export var
copia la variable internavar
en el entorno, donde se hereda e importa como variable en cualquier shell secundario, pero no tiene ningún efecto en un shell primario. Normalmente, se crea un sub-shell para ejecutar un script, y cualquier cambio que realice (incluidas las variables exportadas) se pierde cuando se completa. Para que un script establezca variables en un shell, debe ejecutarse en ese shell, y esto es lo que hace el.
comando: ejecutar el script sin crear un sub-shell. Curiosamente, los scripts ejecutados por.
no necesitan tener permiso ejecutable..
yexport
, el título de esta pregunta no lo llevaría a esperar una respuesta aquí, así que dejaré que mi respuesta permanezca como está, pero gracias por su comentario.No es un solo comando, pero no tiene que volver a escribir toda la ruta que solo usa
!$
(que es el último argumento del comando anterior en el historial del shell).Ejemplo:
fuente
Mediante la creación de alias . Manera muy popular de crear tus propios comandos.
Puede crear un alias sobre la marcha:
Eso es. Si desea mantener ese alias de forma permanente (no solo la sesión actual), coloque ese comando en un archivo de puntos (generalmente ~ / .bash_aliases o ~ / .bash_profile).
fuente
Además de lo que ya se ha sugerido, me gustaría recomendar thefuck . Es un marco de Python para agilizar su proceso de shell solucionando errores. Inspirado en este tweet , todo lo que tiene que hacer es escribir su alias configurado (por defecto
fuck
) e intentará corregir su comando anterior. Una de sus correcciones se comporta de la siguiente manera:fuente