Posso ligar o comando cd?

9

Estou tentando configurar algo em um servidor em que corro, sempre que estou cdem uma public_htmlpasta 95% do tempo, há alguns comandos que sempre executarei para verificar certas coisas.

Existe cdalguma maneira que eu possa ligar, então se o diretório for a public_html, ele executará automaticamente os comandos para mim?

Se eu não conseguir me conectar ao cdcomando, existem outras coisas que eu poderia fazer para alcançar o resultado que estou buscando?

Estou executando o CentOS 5.8.

TMH
fonte

Respostas:

12

Você pode adicionar essa função ao seu .bashrcou a outro arquivo de inicialização (dependendo do seu shell).

cd() {      
   if [ "$1" = "public_html" ]; then
      echo "current dir is my dir"
   fi
   builtin cd "$1"
}
UVV
fonte
Ooh, isso parece interessante. Adicionei isso ao meu .bash_profile e adicionei um echo "Testing..."pouco acima da saída if, mas nada. Preciso fazer algo para aplicar essas alterações?
TMH 27/11
@TomHart Se você não iniciou uma nova sessão, é necessário originar o arquivo na sua sessão atual por. ~/.bash_profile
UVV
@ TomHart parece que não há /bin/cdno meu CentOS, portanto, esta solução pode não funcionar
UVV
Acabei de perceber isso agora. Encontrei esta pergunta que indica por que unix.stackexchange.com/questions/116955/where-is-cd-located . Ainda é uma boa solução para o sistema que realmente possui um / bin / cd embora :).
TMH
1
Não funciona se você cd -P public_htmlou cd ~/public_htmlou tem um comportamento inesperado se você não pode cdentrar public_html.
Stéphane Chazelas
17

Com kshou bash(ou zsh):

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

Com zsh:

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

( chpwdÉ um gancho função que é chamado sempre que muda o diretório de trabalho atual (por meio de cd, pushd, popd...)).

Stéphane Chazelas
fonte
3

O agrupamento cd, um comando existente, não é recomendado.

Uma solução mais universal seria definir um chpwdgancho personalizado no Bash. (De acordo com as tags desta pergunta, suponho que você esteja usando o Bash)

Não há um sistema completo de ganchos projetado no Bash quando comparado com outros invólucros modernos. PROMPT_COMMANDA variável é usada como uma função do gancho, que é equivalente ao precmdgancho no ZSH, fish_promptno Fish. Por enquanto, o ZSH é o único shell que eu conheço que possui um chpwdgancho embutido.

PROMPT_COMMAND

Se definido, o valor é interpretado como um comando a ser executado antes da impressão de cada prompt principal ($ PS1).

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

chpwd Hook in Bash

É fornecido um truque para configurar um chpwdgancho equivalente no Bash com base em 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}"

Desde que nós estamos detectando PWDalteração diretamente, a solução funciona com cd, pushde popd.

Nota : A principal diferença entre nossa chpwdimplementação no Bash e chpwdno ZSH PROMPT_COMMANDé que não é suportada em um shell Bash não interativo.

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: Criar gancho equivalente chpwd no Bash a partir da minha essência.

Para quem quiser uma resposta para ZSH. Use o chpwdgancho no ZSH. Não defina a chpwd()função diretamente. Mais detalhes aqui .

Simba
fonte
1

Não sou especialista em bash, mas aceitaria a resposta do @ UVV e a modificaria um pouco para fazer isso:

  • em vez de public_htmlprocurar, basta verificar algum hook-scriptarquivo no diretório de destino $1, digamos cd_hook.sh,.
  • se houver hook-script, execute-o e siga em frente com ocd

Isso parece mais genérico porque você poderá aplicar o cd-hook a qualquer diretório, se assim o desejar, apenas adicionando um cd_hook.shno referido diretório.

achados e perdidos
fonte
3
Parece genérico, mas você está apresentando uma vulnerabilidade de segurança. Alguém ou algo só precisa plantar um script de gancho no / tmp, por exemplo, para fazer você executar qualquer código na próxima vez que fizer o cd lá. Você deseja pelo menos garantir que o script hook seja de sua propriedade, não um link simbólico, não possa ser gravado por ninguém além de você, que o diretório em que ele está seja gravável apenas por você ... Consulte Mantendo histórico por diretório de trabalho (cf. por sessão shell) para uma abordagem mais segura.
Stéphane Chazelas
Obrigado pelo insight de segurança @ StéphaneChazelas. Eu tenho que admitir que nem pensei nisso.
achados e perdidos
Encontrei esta pergunta ao fazer exatamente isso: se eu estiver em cdalgum lugar, verifique se há um .bashcdarquivo e execute-o, se existir.
DarkWiiPlayer
0

Usando a poderosa abordagem zsh no bash:

Primeiro, uma maneira fácil de estender o 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
}

Inclua no .bashrc:

. ~/.run_scripts

run_scripts ~/.bashrc.d

Você pode criar ~ / .bashrc.d / cdhook com:

#!/bin/bash

chpwd() {
  : #no action
}

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

Agora cabe a você substituir a função:

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