Kann ich mich in den Befehl cd einbinden?


9

Ich versuche, etwas auf einem von mir ausgeführten Server einzurichten. Immer wenn ich mich cdin public_html95% der Fälle in einem Ordner befinde, gibt es einige Befehle, die ich immer ausführen werde, um bestimmte Dinge zu überprüfen.

Gibt es überhaupt eine Möglichkeit, in die ich mich einbinden kann? cdWenn das Verzeichnis a ist public_html, werden die Befehle automatisch für mich ausgeführt?

Wenn ich mich nicht an den cdBefehl anschließen kann, gibt es noch andere Dinge, die ich tun könnte, um das gewünschte Ergebnis zu erzielen?

Ich verwende CentOS 5.8.

Antworten:


12

Sie können diese Funktion zu Ihrer .bashrcoder einer anderen Startdatei hinzufügen (abhängig von Ihrer Shell).

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

Oh, das sieht interessant aus. Ich habe dies zu meinem .bash_profile hinzugefügt und eine echo "Testing..."Ausgabe direkt über der if-, aber nothings-Ausgabe hinzugefügt. Muss ich etwas tun, um diese Änderungen anzuwenden?
TMH

@ TomHart Wenn Sie keine neue Sitzung gestartet haben, müssen Sie die Datei in Ihre aktuelle Sitzung von. ~/.bash_profile
UVV

@ TomHart es scheint, dass es kein /bin/cdin meinem CentOS gibt, also wird diese Lösung möglicherweise nicht funktionieren
UVV

Das habe ich gerade bemerkt. Ich habe diese Frage gefunden, aus der hervorgeht, warum unix.stackexchange.com/questions/116955/where-is-cd-located . Immer noch eine gute Lösung für Systeme, die tatsächlich eine / bin / cd haben :).
TMH

1
Funktioniert nicht, wenn Sie cd -P public_htmloder cd ~/public_htmloder unerwartetes Verhalten haben, wenn Sie nicht cdin können public_html.
Stéphane Chazelas

17

Mit kshoder bash(oder zsh):

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

Mit zsh:

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

( chpwdIst eine Haken - Funktion , die aufgerufen wird , wenn das aktuelle Arbeitsverzeichnis ändert (haft cd, pushd, popd...)).


3

Wrapping cd, ein vorhandener Befehl, wird nicht empfohlen.

Eine universellere Lösung wäre das Definieren eines benutzerdefinierten chpwdHooks in Bash. (Laut Tags dieser Frage gehe ich davon aus, dass Sie Bash verwenden.)

Im Vergleich zu anderen modernen Schalen gibt es in Bash kein komplettes Hakensystem. PROMPT_COMMANDDie Variable wird als Hook-Funktion verwendet, die dem precmdHook in ZSH fish_promptin Fish entspricht. Derzeit ist ZSH die einzige mir bekannte Shell, in die ein chpwdHaken eingebaut ist.

PROMPT_COMMAND

Wenn festgelegt, wird der Wert als Befehl interpretiert, der vor dem Drucken jeder primären Eingabeaufforderung ($ PS1) ausgeführt werden soll.

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

chpwd Haken Sie Bash ein

Es wird ein Trick bereitgestellt, um einen chpwdäquivalenten Hook in Bash basierend auf einzurichten 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}"

Da wir Erfassung PWDdirekt ändern, funktioniert die Lösung mit cd, pushdund popd.

Hinweis : Der Hauptunterschied zwischen unserer chpwdImplementierung in Bash und der chpwdin ZSH besteht darin, dass PROMPT_COMMANDsie in einer nicht interaktiven Bash-Shell nicht unterstützt wird.

Verwendungszweck

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

Quelle: Erstellen Sie chpwd Equivalent Hook in Bash aus meinem Kern.

Für alle, die eine Antwort für ZSH wollen. Verwenden Sie den chpwdHaken in ZSH. Funktion nicht direkt definieren chpwd(). Mehr Details hier .


1

Ich bin kein Bash-Experte, aber ich würde die Antwort von @ UVV nehmen und sie nur ein wenig ändern, damit dies geschieht:

  • Anstatt nach zu suchen public_html, würde ich einfach nach einer hook-scriptDatei im Zielverzeichnis suchen $1, sagen wir cd_hook.sh.
  • Wenn dies hook-scriptvorhanden ist, führen Sie es aus und fahren Sie mit dem fortcd

Dies scheint allgemeiner zu sein, da Sie den cd-hook dann auf jedes Verzeichnis anwenden können, wenn Sie dies wünschen, indem Sie einfach ein cd_hook.shin dieses Verzeichnis einfügen .


3
Es scheint allgemein zu sein, aber Sie führen eine Sicherheitslücke ein. Jemand oder etwas muss nur ein Hook-Skript in / tmp einfügen, damit Sie beim nächsten CD-Vorgang einen beliebigen Code ausführen können. Sie möchten zumindest sicherstellen, dass das Hook-Skript Ihnen gehört, kein Symlink, der von niemand anderem als Ihnen beschreibbar ist, und dass das Verzeichnis, in dem es sich befindet, nur von Ihnen beschreibbar ist ... Siehe Verwalten des Verlaufs pro Arbeitsverzeichnis (vgl. pro Shell-Sitzung) für einen sichereren Ansatz.
Stéphane Chazelas

Vielen Dank für die Sicherheitsinformationen @ StéphaneChazelas. Ich muss zugeben, dass ich nicht einmal darüber nachgedacht habe.
lost-and-found

Ich habe diese Frage dabei gefunden: Wenn ich cdirgendwo bin , suche nach einer .bashcdDatei und führe sie aus, falls sie existiert.
DarkWiiPlayer

0

Verwenden des leistungsstarken zsh-Ansatzes in bash:

Zunächst eine einfache Möglichkeit, Bash zu verlängern:

~ / .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
}

In .bashrc aufnehmen:

. ~/.run_scripts

run_scripts ~/.bashrc.d

Sie können ~ / .bashrc.d / cdhook erstellen mit:

#!/bin/bash

chpwd() {
  : #no action
}

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

Jetzt liegt es an Ihnen, die Funktion zu ersetzen:

#list files after cd
chpwd() {
  ls -lah --color
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.