¿Puedo conectarme al comando cd?


9

Estoy tratando de configurar algo en un servidor que ejecuto, cada vez que entro cden una public_htmlcarpeta el 95% del tiempo hay algunos comandos que siempre ejecutaré para verificar ciertas cosas.

¿Hay alguna forma de conectarme cdpara que si el directorio es a public_html, ejecute automáticamente los comandos por mí?

Si no puedo conectarme al cdcomando, ¿hay alguna otra cosa que pueda hacer para lograr el resultado que busco?

Estoy ejecutando CentOS 5.8.

Respuestas:


12

Puede agregar esta función a su .bashrcu otro archivo de inicio (dependiendo de su shell).

cd() {      
   if [ "$1" = "public_html" ]; then
      echo "current dir is my dir"
   fi
   builtin cd "$1"
}

Ooh, esto se ve interesante. Agregué esto a mi .bash_profile, y agregué un echo "Testing..."poco más arriba de la salida if, pero de nada. ¿Necesito hacer algo para aplicar estos cambios?
TMH

@TomHart Si no inicia una nueva sesión a continuación, usted tiene a la fuente el archivo en su sesión actual. ~/.bash_profile
UVV

@TomHart parece que no hay ninguna /bin/cden mi CentOS, por lo que esta solución podría no funcionar
UVV

Acabo de notar eso ahora. Encontré esta pregunta que indica por qué unix.stackexchange.com/questions/116955/where-is-cd-located . Sigue siendo una buena solución para el sistema que realmente tiene un / bin / cd :).
TMH

1
No funciona si cd -P public_htmlo cd ~/public_htmlo tiene un comportamiento inesperado si no puede cden public_html.
Stéphane Chazelas

17

Con ksho bash(o zsh):

cd() {
  builtin cd "$@" || return
  [ "$OLDPWD" = "$PWD" ] || case $PWD in
      (*/public_html) echo do something
    esac
}

Con zsh:

chpwd()
  case $PWD in
    (*/public_html) echo do something
  esac

( chpwdEs un gancho de función que se llama cada vez que cambia el directorio de trabajo actual (por medio de cd, pushd, popd...)).


3

La envoltura cd, un comando existente, no se recomienda.

Una solución más universal sería definir un chpwdenlace personalizado en Bash. (Según las etiquetas de esta pregunta, supongo que estás usando Bash)

No hay un sistema de gancho completo diseñado en Bash en comparación con otros proyectiles modernos. PROMPT_COMMANDLa variable se utiliza como una función de precmdenlace, que es equivalente al enlace en ZSH, fish_prompten Fish. Por el momento, ZSH es el único shell que he conocido que tiene un chpwdgancho incorporado.

PROMPT_COMMAND

Si se establece, el valor se interpreta como un comando para ejecutar antes de la impresión de cada solicitud principal ($ PS1).

https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#Bash-Variables

chpwd Gancho en Bash

Se proporciona un truco para configurar un chpwdenlace equivalente en Bash basado en PROMPT_COMMAND.

# create a PROPMT_COMMAND equivalent to store chpwd functions
typeset -g CHPWD_COMMAND=""

_chpwd_hook() {
  shopt -s nullglob

  local f

  # run commands in CHPWD_COMMAND variable on dir change
  if [[ "$PREVPWD" != "$PWD" ]]; then
    local IFS=$';'
    for f in $CHPWD_COMMAND; do
      "$f"
    done
    unset IFS
  fi
  # refresh last working dir record
  export PREVPWD="$PWD"
}

# add `;` after _chpwd_hook if PROMPT_COMMAND is not empty
PROMPT_COMMAND="_chpwd_hook${PROMPT_COMMAND:+;$PROMPT_COMMAND}"

Ya que estamos detectando PWDel cambio directamente, la solución trabaja con cd, pushdy popd.

Nota : La principal diferencia entre nuestra chpwdimplementación en Bash y chpwden ZSH es PROMPT_COMMANDque no es compatible con un shell Bash no interactivo.

Uso

_public_html_action() {
  if [[ $PWD == */public_html ]]; then
    # actions
  fi
}

# append the command into CHPWD_COMMAND
CHPWD_COMMAND="${CHPWD_COMMAND:+$CHPWD_COMMAND;}_public_html_action"

Fuente: Crear chpwd Equivalent Hook en Bash desde mi esencia.

Para cualquiera que quiera una respuesta para ZSH. Use chpwdgancho en ZSH. No defina la chpwd()función directamente. Más detalles aquí .


1

No soy un experto en bash, pero tomaría la respuesta de @ UVV y la modificaría un poco para que haga esto:

  • en lugar de la comprobación de public_html, que acababa de comprobar si hay algún hook-scriptarchivo en el directorio de destino $1, por ejemplo, cd_hook.sh.
  • si eso hook-scriptexiste, ejecútelo y continúe con elcd

Esto parece más genérico porque luego podrá aplicar el cdgancho a cualquier directorio si así lo desea, simplemente agregando un cd_hook.shen dicho directorio.


3
Parece genérico, pero está introduciendo una vulnerabilidad de seguridad. Alguien o algo solo necesita plantar un script de gancho en / tmp, por ejemplo, para que ejecute cualquier código la próxima vez que haga un CD allí. Al menos, querrás asegurarte de que el script de gancho sea de tu propiedad, no de un enlace simbólico, que no sea editable por nadie más que tú, que el directorio en el que está solo sea editable por ti ... Consulta Mantener el historial por directorio de trabajo (cf. por sesión de shell) para un enfoque más seguro.
Stéphane Chazelas

Gracias por la información de seguridad @ StéphaneChazelas. Tengo que admitir que ni siquiera lo pensé.
perdido y encontrado el

Encontré esta pregunta al hacer eso: si estoy en cdalgún lugar, busque un .bashcdarchivo y ejecútelo si existe.
DarkWiiPlayer

0

Usando el poderoso enfoque zsh en bash:

Primero, una manera fácil de extender bash:

~ / .runscripts

#load all scripts inside $1 dir

run_scripts()
{
    for script in $1/*; do

        # skip non-executable snippets
        [ -f "$script" ] && [ -x "$script" ] || continue

        # execute $script in the context of the current shell
        . $script
    done
}

Incluir en .bashrc:

. ~/.run_scripts

run_scripts ~/.bashrc.d

Puede crear ~ / .bashrc.d / cdhook con:

#!/bin/bash

chpwd() {
  : #no action
}

cd() {      
   builtin cd $1
   chpwd $1
}

Ahora depende de usted reemplazar la función:

#list files after cd
chpwd() {
  ls -lah --color
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.