Alias ​​a CD en un directorio y llamar a un comando

21

Tengo un .bash_profiley en eso tengo un conjunto de alias. Esos alias en este momento ejecutan un solo comando y fue bastante fácil. Sin embargo, me gustaría hacer dos cosas con un nuevo alias que estoy tratando de crear.

  1. CD en un directorio
  2. Ejecute un comando desde ese directorio
user232103
fuente

Respuestas:

26

Para ejecutar un comando con un directorio de trabajo específico, generalmente se hace

( cd directory && utility )

El paréntesis alrededor del cd ...medio significa que el comando (s) allí se ejecuta en una subshell. Cambiar el directorio de trabajo en un subshell hace que el directorio de trabajo actual del shell que realiza la llamada no cambie, es decir, después de haber llamado a este comando, aún estaría ubicado en el mismo directorio donde comenzó.

Ejemplo:

( cd / && echo "$PWD" )  # will output "/"
echo "$PWD"              # will output whatever directory you were in at the start

Esto no puede convertirse en un alias genérico ya que un alias no puede tomar ningún argumento.

Para un directorio y utilidad específicos , uno podría hacer

alias cdrun='( cd "$HOME/somedir" && ./script.sh )'

pero para el caso general, tendrías que usar una función de shell:

cdrun () {
    ( cd "$1" && shift && command "$@" )
}

o

cdrun () (
    cd "$1" && shift && command "$@"
)

Reemplazar las llaves con paréntesis alrededor del cuerpo de la función hace que la función se ejecute en su propia subshell.

Esto se usaría como

$ cdrun "$HOME/somedir" ./script.sh

que ejecutaría el script script.shubicado en el directorio $HOME/somedir, con $HOME/somedirel directorio de trabajo, o

$ cdrun / ls -l

que le proporcionaría una lista de directorios en "formato largo" del directorio raíz.

La función de shell toma su primer argumento e intenta cambiar a ese directorio. Si eso funciona, desvía el nombre del directorio de los parámetros posicionales (la lista de argumentos de la línea de comando) y ejecuta el comando dado por el resto de los argumentos. commandes un comando incorporado en el shell que simplemente ejecuta sus argumentos como un comando.


Todo esto es necesario si desea ejecutar un comando con un directorio de trabajo modificado . Si solo desea ejecutar un comando ubicado en otro lugar, obviamente podría usar

alias thing='$HOME/somedir/script.sh'

pero esto se ejecutará script.shubicado $HOME/somedircon el directorio actual como el directorio de trabajo.

Otra forma de ejecutar un script ubicado en otro lugar sin cambiar el directorio de trabajo es agregar la ubicación del script a su PATHvariable de entorno, por ejemplo

PATH="$PATH:$HOME/somedir"

Ahora script.shen $HOME/somedirque será capaz de ejecutar desde cualquier lugar sólo por el uso

$ script.sh

Nuevamente, esto no cambia el directorio de trabajo para el comando.

Kusalananda
fuente
2
Excelente, respuesta integral. Sólo pensé que me gustaría mencionar que la definición de función sólo necesita un método de agrupación de comandos y los paréntesis para el subnivel son suficientes: cdrun () ( cd "$1" && shift && command "$@" ).
Anthony G - justicia para Mónica
2
@AnthonyGeoghegan Ah, eso es cierto. Sin { ... }embargo, siempre uso la coherencia con funciones más largas.
Kusalananda
Este Q&A parece hablar de mi situación, y puede ser una mejora en el uso de un entorno pushdy popd(también > /dev/nullsi está tratando de evitar los mensajes de salida también), ¡al tiempo que mantiene el contexto limpio!
Pysis
1
@Pysis Sí, (cd dir && thing)también es mucho más portátil que usar pushdy popd.
Kusalananda
@Kusalananda ¿En serio? Los hice trabajar para al menos varios sistemas.
Pysis
4
alias <name-of-the-alias>='cd <the-directory> && <command>'

Entonces, si desea cambiar el directorio (cd) en la carpeta /var/log/y luego enumerar (ls) sus archivos, puede agregar en su .bash_profilearchivo lo siguiente:

alias logs='cd /var/log/ && ls'
nikolas
fuente
1

Utilizo esta función para ejecutar un solo comando en un directorio diferente:

cd1 () {
  if [ $# -eq 1 ]; then
    command cd -- "$1"
  else
    ( command cd -- "$1" && shift && "$@" )
  fi
}

Una limitación de esta función es que los comodines se completan en relación con el directorio original, no en relación con el directorio donde se ejecuta el comando. Es posible hacerlo mejor en zsh .

Esta función actúa como la ordinaria cdsi se llama con un solo argumento, por lo que puede llamarla cd. (Esta función no admite ninguna opción, pero cdrara vez se utilizan opciones ).

Gilles 'SO- deja de ser malvado'
fuente
-1

Comandos separados con un punto y coma, por ejemplo:

alias do_something='cd /tmp; ls'
John Elliot V
fuente
8
Si cdfalla, obtendrá la lista de directorios del directorio incorrecto. Es mejor usar en &&lugar de ;aquí.
Kusalananda
@Kusalananda tiene razón. Puede encontrar más en esta respuesta
nikolas