Me encuentro repitiendo mucho:
mkdir longtitleproject cd longtitleproject
¿Hay alguna forma de hacerlo en una línea sin repetir el nombre del directorio? Estoy en bash aquí.
Comentarios
Responder
Esto es la única línea que necesita. No se necesita ninguna 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.
Utilice 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 de shell :
cd ~/ mkdir folder && cd !$
terminas en casa (o ~ /)
cd ~/ mkdir newfolder && cd $_
¡¡terminas en una nueva carpeta debajo de casa !! (o ~ / newfolder)
Comentarios
- Por qué diablos esta no es la respuesta aceptada
- @JSmyth Estoy de acuerdo , esta es una sola línea que usa la funcionalidad de shell nativa
- Creo que el OP está tratando de evitar el uso de los dos comandos. Esta respuesta es (casi) tan válida como hacer
mkdir foo && cd foo
, que no es ‘ t útil. - El OP es pidiendo una sola línea que no ‘ t requiera repetir el nombre del directorio, y este es
- Por los votos a favor ‘ s evidente que muchas personas encuentran útil esta respuesta. Yo ‘ diré por qué no ‘ t seleccioné esta respuesta: Yo ‘ m muy es probable que escriba mal
&& cd $_
ya que las teclas están muy lejos de la fila de inicio, por lo que, aunque es técnicamente correcto, ‘ no es ergonómico. Aprecio el hecho de que ‘ no depende del entorno y es ‘ es útil saberlo. ¡Gracias!
Responder
No hay un comando integrado, pero puede escribir fácilmente una función que llamadas mkdir
luego cd
:
mkcd () { mkdir "$1" cd "$1" }
Pon este código en su archivo ~/.bashrc
(o ~/.kshrc
para usuarios de ksh, o ~/.zshrc
para usuarios de zsh). Define una función llamada mkcd
. "$1"
será reemplazada por el argumento de la función cuando la ejecutes.
Esta versión simple tiene varios defectos:
- No puede crear una cadena de subdirectorios a la vez. Solución: pase la opción
-p
amkdir
. (Esto puede ser deseable o no, ya que aumenta el riesgo de que un error tipográfico no se detecte, por ejemplo,mkcd mydierctory/newsub
crearámydierctory
ymydierctory/newsub
cuando pretendías crearnewsub
dentro del existentemydirectory
.) - Si el argumento comienza con
-
pero no es solo-
, luegomkdir
ycd
lo interpretarán como una opción. Si «es solo-
, entoncescd
lo interpretará como$OLDPWD
. Si «s+
seguido de 0 o más dígitos, luegocd
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./
al argumento si es «una ruta relativa. -
mkdir
no sigueCDPATH
, perocd
sí, así que si «has configuradoCDPATH
a un valor que no comienza con.
(una configuración ciertamente algo inusual), entoncescd
puede llevarlo a un directorio diferente al el que se acaba de crear.Anteponer./
a rutas relativas se corrige esto¹ (hace queCDPATH
se ignore). - Si
mkdir
falla, intenta ejecutarcd
. Solución: use&&
para separar los dos comandos.
Aún bastante simple:
mkcd () { case "$1" in /*) :;; *) set -- "./$1";; esac mkdir -p "$1" && cd "$1" }
Esta versión aún tiene el potencial de hacer que cd
vaya a un directorio diferente al que mkdir
acaba de crear en un caso de borde: si el argumento de mkcd
contiene ..
y pasa por un enlace simbólico. Por ejemplo, si el directorio actual es /tmp/here
y mylink
es un enlace simbólico a /somewhere/else
, luego 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 que cd /tmp/mylink; mkdir ../foo; cd ../foo
no cambia al nuevo directorio (/somewhere/else/foo
) pero en /tmp/foo
. Una solución para esto es permitir que el cd
resuelva todos los ..
primero los componentes de la ruta (no tiene «sentido usar foo/..
si foo
no lo hace» t existe, por lo que mkdir
nunca necesita ver ningún ..
).
Llegamos a esto sólido aunque ligeramente sangriento versión:
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 una subcapa para la primera cd
llamar?)
Si mkdir falla, quiero asegurarme de no cambiar el directorio actual. Volver 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 para no tener que volver a escribir la palabra de la línea anterior:
- Escriba
cd
, luego Esc . (o Alt + . ) para insertar el último argumento del comando anterior. -
cd !$
ejecutacd
en el último argumento del comando anterior. - Presione Arriba para recuperar la línea de comando anterior, luego edítela para cambiar
mkdir
acd
.
¹ tenga en cuenta que no funciona en ksh93 desde la u+
versión , corregida en 93u + m / 1.0.0-alpha + d1483150 2021-01-05
Comentarios
- ¡Gracias! el Esc. me parece el más conveniente, ¿la secuencia de teclas tener alguna m especial ¿eaning?
- Es ‘ s solo el Bash (y se hereda de
ksh
, y también funciona enzsh
) secuencia para » repetir la última palabra del comando anterior «. Lo uso con bastante frecuencia. - @Gilles I ‘ estoy empezando a pensar que el » Gilles » cuenta en realidad compartida por un panel de expertos. 😉
- @StephaneChazelas
/a/b/..//
realmente funcionaría, pero no/a/b/../c
. Reparado. Yo ‘ he planteado la pregunta a una audiencia más amplia. -
mkcd() { mkdir -p "$1" && cd "$1"; }
doesn ‘ t 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
que es lo que se creó (y lo que esperaba).bash
crea y cambia erróneamente a/var/tmp/somewhere/foo
.
Respuesta
Nunca se me hubiera ocurrido crear un script para este comportamiento porque ingreso 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, completar el nombre de archivo es su amigo en tales situaciones. Si su nuevo directorio era el único archivo en la carpeta, un rápido doble TAB le daría el nuevo directorio sin volver a ingresarlo.
Aunque es genial que bash le permita para programar tareas tan comunes como sugieren las otras respuestas, creo que es mejor aprender las funciones de edición de línea de comandos que ofrece bash para que cuando esté trabajando en otra máquina no se pierda el azúcar sintáctico que brindan sus scripts personalizados.
Comentarios
- ¿Existe un buen lugar para conocer las peculiaridades de bash más importantes como esta?
- @ dominicbri7 Generalmente viene bajo » edición de la línea de comando bash » Al buscar en Google, el resultado es el siguiente web.mit.edu/gnu/doc/html/features_7.html Más específicamente,! $ es un ejemplo de un designador de palabras, consulte gnu.org/software /bash/manual/bashref.html#Word-Designators
Responder
Si usa Oh My Zsh, hay un comando llamado take que hace exactamente esto. Se vería así.
take myfolder
En realidad encontré este por accidente. Simplemente miré y aparece en este cheatsheat de la wiki de Oh My Zsh GitHub. Es un comando bastante útil, y aparentemente muy fácil de crear usted mismo.
Comentarios
- Nunca supe acerca de
take
🙂 ¡Perfecto! Por cierto – iTerm2 con Oh My Zsh. En realidad, hay 3 respuestas perfectas aquí. Esta, la de @jes ú s-carrera, y la respuesta seleccionada. Depende de su configuración y preferencia.
Respuesta
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.
Comentarios
- La opción
-p
para mkdir suprimirá los errores. - mcd es un comando ya existente. Aunque ‘ acaba de dar un ejemplo, yo mismo lo usé como ‘ una letra más corta que mkcd.
- @Dharmit Shah: ¿Cuál es el comando
mcd
existente? ¿Qué paquete o proyecto proporciona este comando? - mtools proporciona el comando mcd. Su página de manual dice » El comando mcd se usa para cambiar el directorio de trabajo de mtools en el disco MS-DOS. »
Respuesta
O simplemente puede crear una variable corta sobre la marcha y usarla dos veces x = longproject ; mkdir $x ; cd $x
– lo que admito es aún más largo que usar una función shellscript 🙂
Responder
Esta es una cosa simple de hacer en un script / función bash. Creé un tutorial muy legible y suficientemente documentado que incluye scripts que funcionan tanto en Linux como en MacOS (esto también se mantendrá en el futuro).
Mi objetivo para la complejidad del tutorial es: escrito para un público objetivo con el único requisito previo es que el usuario tenga pulso y pueda leer en inglés, así que envíe sus comentarios si necesita ayuda.
https://github.com/craigopie/shellscripts
mcdir() { if [ $# -eq 0 ] || [ $1 = "-h" ] || [ $1 = "--help" ] then echo "Usage: [option...] {directory}" echo " -p, --path Create all directories in path " echo " -h, --help Shows this helpful information " echo return 0 fi ## create directory with a path if [ $1 = "-p" ] || [ $1 = "--path" ] then mkdir -p "$2" &>/dev/null if [ $? -gt 0 ] then echo "There was a problem creating your directory." return 1 fi cd "$2" &>/dev/null if [ $? -gt 0 ] then echo "Unable to change into that directory." return 1 fi return 0 fi ## create directory in this location mkdir "$1" &>/dev/null if [ $? -gt 0 ] then echo "There was a problem creating your directory." return 1 fi cd "$1" &>/dev/null if [ $? -gt 0 ] then echo "Unable to change into that directory." return 1 fi return 0 } export -f mcdir
Para instalar esto tienes dos opciones:
- Primero, agregue la función a su
.bashrc
archivo. - El segundo es agregar el archivo a su ruta y luego obtenga el archivo en su
.bash_profile
archivo.
De nuevo, el archivo README es muy detallado sobre cómo hacer esto.
¡Buena suerte!
Respuesta
Aquí «una pequeña variante que vale la pena mencionar:
function mkdir() { local dir=$1 command mkdir "$dir" && cd "$dir" }
Agrega esto a yo ur ~/.bash_profile
y luego puede usar mkdir
normalmente (una vez que «ve source
» d it), excepto que ahora ejecutará la función anterior en lugar del comando mkdir
estándar.
Tenga en cuenta que esto no valida la entrada según el respuesta de Gilles , pero demuestra cómo se pueden anular (efectivamente) las funciones integradas.
De la docs (parafraseando ligeramente):
command mkdir [args]
ejecutamkdir
conargs
ignorando cualquier función de shell llamadamkdir
. Solo se ejecutan los comandos integrados de shell o los comandos que se encuentran al buscar en la RUTA. Si hay una función de shell llamadals
, ejecutarcommand ls
dentro de la función ejecutará el comando externols
en lugar de llamar a la función de forma recursiva
Creo que builtin
logra un resultado similar a command
.
Comentarios
- definitivamente debes citar
$dir
- @Jeff, estuvo de acuerdo, pero la respuesta aceptada tiene toda la validación que uno necesitaría.Yo ‘ solo presento el uso de
command
como alternativa.
Respuesta
Agregar función auxiliar a BASH, ZSH o KSH
Cree el comando mkcd
en su entorno en una línea
echo -e "mkcd() {\n mkdir -p "$1" && cd $_\n}" >> ~/.${0//-/}rc && . ~/.${0//-/}rc
Responder
Si está utilizando Oh-my-zsh , el comando take
hará el truco. Eche un vistazo a la hoja de referencia .
Respuesta
Simplemente automatizó las respuestas anteriores y creó 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 por 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 ingrese directamente en ese directorio.
Comentarios
- Sugiere escribir un script (en un archivo) cuyo único propósito es agregarlo al
~/.bashrc
archivo (con una respuesta que ya se ha dado)? ¿Y cómo sugiere crear este scriptmkcd.sh
? ¿Con un editor, quizás? Esto parece más trabajo que simplemente editar~/.bashrc
. ¿Qué ventaja tiene esto sobre la respuesta aceptada? ………………………………………………………………… P.S. Esto fallará debido a problemas de citas, lo que me dice que ni siquiera lo ha intentado usted mismo. - Lamento decirlo, pero sí, como escribí en mi respuesta, utilicé las respuestas anteriores. Funciona. Si no ‘ no me cree, inténtelo. Y sobre no intentarlo, usé mi día completo para escribir tales scripts en bash y python hoy.
- Probé lo que escribiste. no funciona.
mcd
de unix.stackexchange.com/questions/6628/…mkdir longtitleproject
luegocd !^