Me encuentro repitiendo mucho de:
mkdir longtitleproject
cd longtitleproject
¿Hay alguna manera de hacerlo en una línea sin repetir el nombre del directorio? Estoy de fiesta aquí.
mkdir longtitleproject
entoncescd !^
Me encuentro repitiendo mucho de:
mkdir longtitleproject
cd longtitleproject
¿Hay alguna manera de hacerlo en una línea sin repetir el nombre del directorio? Estoy de fiesta aquí.
mkdir longtitleproject
entoncescd !^
Respuestas:
No hay un comando incorporado, pero puede escribir fácilmente una función que llame a mkdir
continuación cd
:
mkcd () {
mkdir "$1"
cd "$1"
}
Ponga este código en su ~/.bashrc
archivo (o ~/.kshrc
para usuarios de ksh, o ~/.zshrc
para usuarios de zsh). Define una función llamada mkcd
. "$1"
será reemplazado por el argumento de la función cuando la ejecutes.
Esta versión simple tiene varios defectos:
-p
opción a mkdir
. (Esto puede o no ser deseable, ya que aumenta el riesgo de que un error tipográfico pase desapercibido, por ejemplo, mkcd mydierctory/newsub
se creará felizmente mydierctory
y mydierctory/newsub
cuando se pretende crear newsub
dentro de lo existente mydirectory
).-
, pero no es justo -
, entonces mkdir
y cd
lo interpretará como una opción. Si es justo -
, entonces cd
lo interpretará en el sentido $OLDPWD
. Si es +
seguido por 0 o más dígitos, cd
en zsh lo interpretará como un índice en la pila de directorios. Puede solucionar el primer problema, pero no los otros dos, pasando --
antes del argumento. Puede solucionar todos estos problemas anteponiendo ./
el argumento si es una ruta relativa.mkdir
no sigue CDPATH
, pero cd
sí, así que si ha establecido CDPATH
un valor que no comienza con .
(una configuración ciertamente inusual), cd
puede llevarlo a un directorio diferente al que acaba de crear. Anteponer ./
rutas relativas soluciona esto (hace CDPATH
que se ignore).mkdir
falla, intenta ejecutarse cd
. Solución: se usa &&
para separar los dos comandos.Todavía bastante simple:
mkcd () {
case "$1" in /*) :;; *) set -- "./$1";; esac
mkdir -p "$1" && cd "$1"
}
Esta versión todavía tiene el potencial de hacer que cd
vaya a un directorio diferente del que mkdir
acaba de crear en un caso extremo: si el argumento mkcd
contiene ..
y pasa a través de un enlace simbólico. Por ejemplo, si el directorio actual es /tmp/here
y mylink
es un enlace simbólico /somewhere/else
, mkdir mylink/../foo
crea /somewhere/else/foo
mientras que cd mylink/../foo
cambia a foo
. No es suficiente buscar enlaces simbólicos en el argumento, porque el shell también rastrea enlaces simbólicos en su propio directorio actual, por lo cd /tmp/mylink; mkdir ../foo; cd ../foo
que no cambia al nuevo directorio ( /somewhere/else/foo
) sino a /tmp/foo
. Una solución para esto es dejar que el cd
incorporado resuelva todos los ..
componentes de la ruta primero (no tiene sentido usar foo/..
sifoo
no existe, por lo que mkdir
nunca necesita ver ninguno ..
).
Llegamos a esta versión robusta aunque un poco sangrienta:
mkcd () {
case "$1" in
*/..|*/../) cd -- "$1";; # that doesn't make any sense unless the directory already exists
/*/../*) (cd "${1%/../*}/.." && mkdir -p "./${1##*/../}") && cd -- "$1";;
/*) mkdir -p "$1" && cd "$1";;
*/../*) (cd "./${1%/../*}/.." && mkdir -p "./${1##*/../}") && cd "./$1";;
../*) (cd .. && mkdir -p "${1#.}") && cd "$1";;
*) mkdir -p "./$1" && cd "./$1";;
esac
}
(Ejercicio: ¿por qué estoy usando un subshell para la primera cd
llamada?)
Si mkdir falla, quiero asegurarme de no cambiar el directorio actual. Cambiar de nuevo con cd o $ OLDPWD no es lo suficientemente bueno si el shell no tiene permiso para cambiar a su directorio actual. Además, llamar a cd actualiza OLDPWD, por lo que solo queremos hacerlo una vez (o restaurar OLDPWD).
También hay formas menos especializadas de no tener que volver a escribir la palabra de la línea anterior:
cd
, luego Esc .(o Alt+ .) para insertar el último argumento del comando anterior.cd !$
se ejecuta cd
en el último argumento del comando anterior.mkdir
a cd
.ksh
, y también funciona zsh
) para "repetir la última palabra del comando anterior". Lo uso con bastante frecuencia.
/a/b/..//
realmente funcionaría pero no /a/b/../c
. Fijo. He planteado la pregunta a un público más amplio.
mkcd() { mkdir -p "$1" && cd "$1"; }
no parece ser un problema en (mi instancia de) zsh. mkdir -p /var/tmp/somewhere/else /tmp/here; cd /tmp/here; ln -s /var/tmp/somewhere/else mylink; mkdir -p mylink/../foo && cd mylink/../foo; pwd
(incluye la configuración y) muestra /tmp/here/foo
cuál es lo que se creó (y lo que esperaba). bash
erróneamente crea y cambia a /var/tmp/somewhere/foo
.
Esta es la línea que necesita. No se necesita otra configuración:
mkdir longtitleproject && cd $_
La $_
variable, en bash, es el último argumento dado al comando anterior. En este caso, el nombre del directorio que acaba de crear. Como se explica en man bash
:
_ At shell startup, set to the absolute pathname used to invoke
the shell or shell script being executed as passed in the envi‐
ronment or argument list. Subsequently, expands to the last
argument to the previous command, after expansion. Also set to
the full pathname used to invoke each command executed and
placed in the environment exported to that command. When check‐
ing mail, this parameter holds the name of the mail file cur‐
rently being checked."$_" is the last argument of the previous command.
Use cd $_
para recuperar el último argumento del comando anterior en lugar de cd !$
porque cd !$
da el último argumento del comando anterior en el historial del shell :
cd ~/
mkdir folder && cd !$
terminas en casa (o ~ /)
cd ~/
mkdir newfolder && cd $_
terminas en una nueva carpeta debajo de casa !! (o ~ / nueva carpeta)
mkdir foo && cd foo
, lo cual no es útil.
Nunca se me habría ocurrido escribir este comportamiento porque escribo lo siguiente casi cada hora ...
$ mkdir someDirectory<ENTER>
$ cd !$
donde bash amablemente sustituye !$
con la última palabra de la última línea; es decir, el nombre de directorio largo que ingresó.
Además, la finalización del nombre de archivo es su amigo en tales situaciones. Si su nuevo directorio fuera el único archivo en la carpeta, un doble rápido TABle daría el nuevo directorio sin tener que volver a ingresarlo.
Aunque es genial que bash le permita crear secuencias de comandos de tareas tan comunes como sugieren las otras respuestas, creo que es mejor aprender las características de edición de línea de comandos que bash tiene para ofrecer para que cuando trabaje en otra máquina no se pierda la sintaxis azúcar que proporcionan sus scripts personalizados.
Según ¿Qué personalizaciones ha realizado en su perfil de shell para aumentar la productividad? así es como lo hago:
# make a directory and cd to it
mcd()
{
test -d "$1" || mkdir "$1" && cd "$1"
}
significa que también funciona si el directorio ya existe.
-p
opción de mkdir suprimirá los errores.
mcd
comando existente ? ¿Qué paquete o proyecto proporciona este comando?
Si usa Oh My Zsh, hay un comando llamado take que hace exactamente esto. Se vería algo así.
take myfolder
En realidad encontré este por accidente. Acabo de mirar y aparece en este truco del wiki Oh My Zsh GitHub. Es un comando bastante útil, y aparentemente muy fácil de crear.
take
:) ¡Perfecto! por cierto - iTerm2 con Oh My Zsh. En realidad, hay 3 respuestas perfectas aquí. Este, el de @ jesús-carrera, y la respuesta seleccionada. Depende de su configuración y preferencia.
Aquí hay una ligera variante que vale la pena mencionar:
function mkdir() {
local dir=$1
command mkdir "$dir" && cd "$dir"
}
Agregue esto a su ~/.bash_profile
y luego puede usarlo mkdir
normalmente (una vez que lo haya source
hecho), excepto que ahora ejecutará la función anterior en lugar del mkdir
comando estándar .
Tenga en cuenta que esto no valida la entrada según la respuesta aceptada por Gilles , sino que demuestra cómo puede (efectivamente) anular las incorporaciones.
De los documentos (parafraseando ligeramente):
command mkdir [args]
corremkdir
conargs
ignorando cualquier función de shell llamadomkdir
. Solo se ejecutan los comandos incorporados de shell o los comandos encontrados al buscar la RUTA. Si hay una función de shell llamadals
, la ejecucióncommand ls
dentro de la función ejecutará el comando externo enls
lugar de llamar a la función de forma recursiva
Creo que builtin
logra un resultado similar a command
.
$dir
command
como alternativa.
Crea mkcd
comandos para tu entorno en una línea
echo -e 'mkcd() {\n mkdir -p "$1" && cd $_\n}' >> ~/.${0//-/}rc && . ~/.${0//-/}rc
Hice un script que crea el directorio y luego los cd's, luego le di un alias. Y aquí hay un resumen donde lo describo.
https://gist.github.com/rehnen/34236d6ff270ccaa74b6#mkdir-like-it-was-meant-to-be
Simplemente automaticé las respuestas anteriores e hice un script ejecutable único:
fun='
mkcd ()
{
mkdir -p -- "$1" && cd -P -- "$1"
}'
echo "$fun" >> ~/.bashrc
Simplemente copie esto en un nuevo archivo mkcd.sh
y ejecútelo solo una vez en la terminal bash mkcd.sh
. Luego, ejecute source ~/.bashrc
para que funcione en la sesión actual.
Después de esto, puede usar mkcd some_dir
para crear e ingresar directamente en ese directorio.
~/.bashrc
archivo (con una respuesta que ya se ha dado)? ¿Y cómo sugieres crear este mkcd.sh
script? ¿Con un editor, tal vez? Esto parece más trabajo que solo editar ~/.bashrc
. ¿Qué ventaja tiene esto sobre la respuesta aceptada? ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... PD: Esto fallará debido a problemas de citas, lo que me dice que ni siquiera lo ha intentado usted mismo.
mcd
de unix.stackexchange.com/questions/6628/…