Czy mogę podłączyć się do polecenia cd?

9

Próbuję skonfigurować coś na uruchamianym przeze mnie serwerze, kiedy tylko cdw public_html95% przypadków znajduję się w folderze, jest kilka poleceń, które zawsze uruchamiam, aby sprawdzić pewne rzeczy.

Czy w każdym razie mogę się podłączyć, cdwięc jeśli katalog to public_html, to automatycznie uruchomi dla mnie polecenia?

Jeśli nie mogę się przyłączyć do cdpolecenia, czy mogę zrobić coś innego, aby osiągnąć wynik, którego szukam?

Używam CentOS 5.8.

TMH
źródło

Odpowiedzi:

12

Możesz dodać tę funkcję do swojego .bashrclub innego pliku startowego (w zależności od powłoki).

cd() {      
   if [ "$1" = "public_html" ]; then
      echo "current dir is my dir"
   fi
   builtin cd "$1"
}
UVV
źródło
Och, to wygląda interesująco. Dodałem to do mojego .bash_profile i dodałem echo "Testing..."tuż powyżej wyjścia if, ale nic. Czy muszę coś zrobić, aby zastosować te zmiany?
TMH
@TomHart Jeśli nie rozpocząłeś nowej sesji, musisz pobrać plik do bieżącej sesji do. ~/.bash_profile
UVV
@TomHart wygląda na to, że nie ma go /bin/cdw moim CentOS, więc to rozwiązanie może nie działać
UVV
Właśnie to zauważyłem. Znalazłem to pytanie, które wyjaśnia, dlaczego unix.stackexchange.com/questions/116955/where-is-cd-located . Nadal dobre rozwiązanie dla systemu, który faktycznie ma / bin / cd :).
TMH
1
Nie działa, jeśli cd -P public_htmlalbo cd ~/public_htmlczy ma nieoczekiwane zachowanie, jeśli nie można cddo public_html.
Stéphane Chazelas
17

Za pomocą kshlub bash(lub zsh):

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

Z zsh:

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

( chpwdTo hak funkcja, która jest wywoływana, gdy zmienia bieżący katalog roboczy (w drodze cd, pushd, popd...)).

Stéphane Chazelas
źródło
3

Zawijanie cd, istniejące polecenie, nie jest zalecane.

Bardziej uniwersalnym rozwiązaniem byłoby zdefiniowanie niestandardowego chpwdhaka w Bash. (Zgodnie z tagami tego pytania, zakładam, że używasz Bash)

W Bash nie ma kompletnego systemu haczyków w porównaniu z innymi nowoczesnymi pociskami. PROMPT_COMMANDZmienna jest używana jako funkcja hook, która jest równoważna precmdhookowi w ZSH, fish_promptw Fish. Na razie ZSH jest jedyną znaną powłoką, która ma chpwdwbudowany hak.

PROMPT_COMMAND

Jeśli jest ustawiony, wartość jest interpretowana jako polecenie do wykonania przed wydrukowaniem każdego monitu podstawowego ($ PS1).

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

chpwd Hook in Bash

Podano sztuczkę, aby ustawić chpwdrównoważny hak w Bash na podstawie 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}"

Ponieważ jesteśmy wykrywania PWDbezpośrednio zmianę, rozwiązanie współpracuje z cd, pushdorazpopd .

Uwaga : Główną różnicą między naszą chpwdimplementacją w Bash a chpwdZSH jest:PROMPT_COMMAND nie jest obsługiwana w nieinteraktywnej powłoce Bash.

Stosowanie

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

Źródło: Utwórz chpwd ekwiwalentny hak w Bashu z mojej treści.

Dla każdego, kto chce odpowiedzi na ZSH. Użyj chpwdhaka w ZSH. Nie definiuj chpwd()funkcji bezpośrednio. Więcej szczegółów tutaj .

Simba
źródło
1

Nie jestem ekspertem od bash, ale wziąłbym odpowiedź @ UVV i trochę ją zmodyfikowałem, aby to zrobiło:

  • zamiast sprawdzania public_html, ja po prostu sprawdzić na jakimś hook-scriptpliku w katalogu docelowym $1, mówią cd_hook.sh.
  • jeśli hook-scriptistnieje, uruchom go i przejdź docd

Wydaje się to bardziej ogólne, ponieważ wtedy możesz zastosować cd-hook do dowolnego katalogu, jeśli tak wybierzesz, po prostu dodając a cd_hook.shdo wspomnianego katalogu.

zagubiony i znaleziony
źródło
3
Wydaje się to ogólne, ale wprowadza się lukę w zabezpieczeniach. Ktoś lub coś musi tylko umieścić skrypt przechwytujący na przykład w / tmp, aby uruchomić kolejny kod przy następnym zapisywaniu dysku CD. Chcesz przynajmniej upewnić się, że skrypt przechwytujący jest własnością użytkownika, a nie dowiązaniem symbolicznym, nie do zapisania przez nikogo innego niż ciebie, że katalog, w którym się znajduje, jest zapisywalny tylko przez ciebie ... Zobacz Prowadzenie historii według katalogu roboczego (por. na sesję powłoki) dla bezpieczniejszego podejścia.
Stéphane Chazelas
Dzięki za wgląd w bezpieczeństwo @ StéphaneChazelas. Muszę przyznać, że nawet o tym nie myślałem.
zagubiony i znaleziony
Znalazłem to pytanie, robiąc właśnie to: jeśli cdgdzieś, sprawdź .bashcdplik i uruchom go, jeśli istnieje.
DarkWiiPlayer,
0

Używanie potężnego podejścia zsh w bash:

Najpierw prosty sposób na przedłużenie 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
}

Uwzględnij w .bashrc:

. ~/.run_scripts

run_scripts ~/.bashrc.d

Możesz utworzyć ~ / .bashrc.d / cdhook za pomocą:

#!/bin/bash

chpwd() {
  : #no action
}

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

Teraz możesz zmienić funkcję:

#list files after cd
chpwd() {
  ls -lah --color
}
albfan
źródło