Puis-je me connecter à la commande cd?

9

Je suis en train de quelque chose ensemble sur un serveur je lance, chaque fois que je cdenpublic_html dossier 95% du temps, il y a quelques commandes que je vais toujours exécuter pour vérifier certaines choses.

Y a-t-il de toute façon je peux me connecter cddonc si le répertoire est unpublic_html , il exécutera automatiquement les commandes pour moi?

Si je ne peux pas me connecter au cd commande, puis-je faire autre chose pour atteindre le résultat que je recherche?

J'utilise CentOS 5.8.

TMH
la source

Réponses:

12

Vous pouvez ajouter cette fonction à votre .bashrcou à un autre fichier de démarrage (selon votre shell).

cd() {      
   if [ "$1" = "public_html" ]; then
      echo "current dir is my dir"
   fi
   builtin cd "$1"
}
UVV
la source
Ooh, ça a l'air intéressant. J'ai ajouté cela à mon .bash_profile et ajouté echo "Testing..."juste au-dessus de la sortie if, mais rien. Dois-je faire quelque chose pour appliquer ces modifications?
TMH
@TomHart Si vous n'avez pas commencé une nouvelle session, vous devez source le fichier dans votre session actuelle par. ~/.bash_profile
UVV
@TomHart il semble qu'il n'y ait pas /bin/cddans mon CentOS, donc cette solution pourrait ne pas fonctionner
UVV
Je viens de le remarquer maintenant. J'ai trouvé cette question qui indique pourquoi unix.stackexchange.com/questions/116955/where-is-cd-located . C'est quand même une bonne solution pour les systèmes qui ont un / bin / cd :).
TMH
1
Ne fonctionne pas si vous cd -P public_htmlou cd ~/public_htmlou avez un comportement inattendu si vous ne pouvez pas cdentrer public_html.
Stéphane Chazelas
17

Avec kshou bash(ou zsh):

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

Avec zsh:

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

( chpwdEst un crochet fonction qui est appelée chaque fois que le répertoire de travail courant change (par voie de cd, pushd, popd...)).

Stéphane Chazelas
la source
3

L'encapsulation cd, une commande existante, n'est pas recommandée.

Une solution plus universelle consisterait à définir un chpwdcrochet personnalisé dans Bash. (Selon les balises de cette question, je suppose que vous utilisez Bash)

Il n'y a pas de système de crochets complet conçu dans Bash par rapport à d'autres coquilles modernes. PROMPT_COMMANDvariable est utilisée comme une fonction de crochet, ce qui équivaut à precmdcrochet dans ZSH, fish_promptdans Fish. Pour le moment, ZSH est le seul shell que j'ai connu à avoir un chpwdcrochet intégré.

PROMPT_COMMAND

Si elle est définie, la valeur est interprétée comme une commande à exécuter avant l'impression de chaque invite principale ($ PS1).

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

chpwd Hook in Bash

Une astuce est fournie pour configurer un chpwdhook équivalent dans Bash basé sur 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}"

Puisque nous détectons le PWDchangement directement, la solution fonctionne avec cd, pushdet popd.

Remarque : La principale différence entre notre chpwdimplémentation dans Bash et chpwddans ZSH est qu'elle PROMPT_COMMANDn'est pas prise en charge dans un shell Bash non interactif.

Usage

_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"

Source: Créer un crochet équivalent chpwd dans Bash à partir de mon essentiel.

Pour tous ceux qui veulent une réponse pour ZSH. Utilisez le chpwdcrochet dans ZSH. Ne définissez pas chpwd()directement la fonction. Plus de détails ici .

Simba
la source
1

Je ne suis pas un expert bash mais je prendrais la réponse de @ UVV et la modifierais un peu pour qu'elle fasse ceci:

  • au lieu de vérifier public_html, je vérifie simplement un hook-scriptfichier dans le répertoire cible $1, par exemple cd_hook.sh.
  • si cela hook-scriptexiste, exécutez-le et passez à lacd

Cela semble plus générique car vous seriez alors en mesure d'appliquer le cdcrochet à n'importe quel répertoire si vous le souhaitez, en ajoutant simplement un cd_hook.shdans ledit répertoire.

perdu et trouvé
la source
3
Cela semble générique, mais vous introduisez une vulnérabilité de sécurité. Quelqu'un ou quelque chose n'a besoin que de planter un hook hook dans / tmp par exemple pour vous faire exécuter n'importe quel code la prochaine fois que vous y allez. Vous voudriez au moins vous assurer que le hook-script vous appartient, pas un lien symbolique, non accessible en écriture par quelqu'un d'autre que vous, que le répertoire dans lequel il se trouve n'est accessible qu'en écriture par vous ... Voir Conservation de l'historique par répertoire de travail (cf. par session shell) pour une approche plus sûre.
Stéphane Chazelas
Merci pour les informations de sécurité @ StéphaneChazelas. Je dois admettre que je n'y ai même pas pensé.
perdu-retrouvé
J'ai trouvé cette question en faisant exactement cela: si je cdquelque part, recherchez un .bashcdfichier et exécutez-le s'il existe.
DarkWiiPlayer
0

Utiliser une approche zsh puissante dans bash:

Tout d'abord, un moyen simple d'étendre 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
}

Inclure dans .bashrc:

. ~/.run_scripts

run_scripts ~/.bashrc.d

Vous pouvez créer ~ / .bashrc.d / cdhook avec:

#!/bin/bash

chpwd() {
  : #no action
}

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

A vous maintenant de remplacer la fonction:

#list files after cd
chpwd() {
  ls -lah --color
}
albfan
la source