Posso collegarmi al comando cd?


9

Sto cercando di impostare qualcosa su un server che eseguo, quando mai cdin una public_htmlcartella il 95% delle volte ci sono alcuni comandi che eseguirò sempre per controllare alcune cose.

Posso comunque collegarmi, cdquindi se la directory è a public_html, eseguirà automaticamente i comandi per me?

Se non riesco ad agganciare il cdcomando, ci sono altre cose che posso fare per ottenere il risultato che sto cercando?

Sto usando CentOS 5.8.

Risposte:


12

È possibile aggiungere questa funzione al proprio .bashrco ad altri file di avvio (a seconda della shell).

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

Ooh, sembra interessante. Ho aggiunto questo al mio .bash_profile e ho aggiunto un echo "Testing..."output appena sopra l'if, ma niente. Devo fare qualcosa per applicare queste modifiche?
TMH,

@TomHart Se non hai avviato una nuova sessione, devi procurarti il ​​file nella sessione corrente entro. ~/.bash_profile
UVV

@TomHart sembra che non ci sia /bin/cdnel mio CentOS, quindi questa soluzione potrebbe non funzionare
UVV

L'ho appena notato ora. Ho trovato questa domanda che spiega perché unix.stackexchange.com/questions/116955/where-is-cd-located . Comunque una buona soluzione per un sistema che in realtà ha un / bin / cd però :).
TMH,

1
Non funziona se si cd -P public_htmlo cd ~/public_htmlo ha un comportamento imprevisto se non è possibile cdin 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

( chpwdÈ un gancio funzione chiamata ogni volta che la directory di lavoro corrente cambia (mediante cd, pushd, popd...)).


3

Il wrapping cd, un comando esistente, non è raccomandato.

Una soluzione più universale sarebbe la definizione di un chpwdhook personalizzato in Bash. (Secondo i tag di questa domanda, suppongo che tu stia usando Bash)

Non esiste un sistema di aggancio completo progettato in Bash rispetto ad altri gusci moderni. PROMPT_COMMANDvariabile viene utilizzata come funzione hook, che equivale a precmdhook in ZSH, fish_promptin Fish. Per ora, ZSH è l'unica shell che ho conosciuto che ha un chpwdhook incorporato.

PROMPT_COMMAND

Se impostato, il valore viene interpretato come un comando da eseguire prima della stampa di ciascun prompt primario ($ PS1).

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

chpwd Hook in Bash

Viene fornito un trucco per configurare un chpwdhook equivalente in Bash basato su 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}"

Dal momento che stiamo rilevando PWDdirettamente il cambiamento, la soluzione funziona con cd, pushde popd.

Nota : la differenza principale tra la nostra chpwdimplementazione in Bash e chpwdin ZSH PROMPT_COMMANDnon è supportata in una shell Bash non interattiva.

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"

Fonte: Crea chpwd Hook equivalente in Bash dal mio succo.

Per chiunque desideri una risposta per ZSH. Utilizzare il chpwdgancio in ZSH. Non definire la chpwd()funzione direttamente. Maggiori dettagli qui .


1

Non sono un esperto di bash ma prenderei la risposta di @ UVV e la modificherei un po 'in modo che faccia questo:

  • invece di controllare public_html, controllerei solo qualche hook-scriptfile nella directory di destinazione $1, per esempio cd_hook.sh.
  • se hook-scriptesiste, eseguilo e vai avanti concd

Questo sembra più generico perché si sarebbe quindi in grado di applicare l' cdhook a qualsiasi directory, se lo si desidera, semplicemente aggiungendo un cd_hook.shnella suddetta directory.


3
Sembra generico, ma stai introducendo una vulnerabilità di sicurezza. Qualcuno o qualcosa deve solo inserire un hook-script in / tmp per esempio per farti eseguire qualsiasi codice la prossima volta che li cd. Dovresti almeno assicurarti che l'hook-script sia di tua proprietà, non un collegamento simbolico, non scrivibile da nessuno tranne te, che la directory in cui si trova sia scrivibile solo da te ... Vedi Mantenere la cronologia per directory di lavoro (cfr. per sessione di shell) per un approccio più sicuro.
Stéphane Chazelas,

Grazie per la visione di sicurezza @ StéphaneChazelas. Devo ammettere che non ci ho nemmeno pensato.
perso e trovato il

Ho trovato questa domanda mentre facevo proprio questo: se cdda qualche parte, cerco un .bashcdfile ed eseguilo se esiste.
DarkWiiPlayer

0

Utilizzando il potente approccio zsh in bash:

Innanzitutto un modo semplice per estendere 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
}

Includi in .bashrc:

. ~/.run_scripts

run_scripts ~/.bashrc.d

Puoi creare ~ / .bashrc.d / cdhook con:

#!/bin/bash

chpwd() {
  : #no action
}

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

Ora tocca a te sostituire la funzione:

#list files after cd
chpwd() {
  ls -lah --color
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.