Могу ли я подключиться к команде cd?

9

Я пытаюсь что-то настроить на сервере, который я запускаю, когда cdв public_html95% случаев в папке всегда есть несколько команд, которые я всегда запускаю для проверки определенных вещей.

Можно ли в любом случае подключиться, cdчтобы, если каталог был public_html, он автоматически запускал для меня команды?

Если я не могу подключиться к cdкоманде, могу ли я сделать что-нибудь еще, чтобы добиться результата, к которому я стремлюсь?

Я использую CentOS 5.8.

TMH
источник

Ответы:

12

Вы можете добавить эту функцию в ваш .bashrcили другой файл запуска (в зависимости от вашей оболочки).

cd() {      
   if [ "$1" = "public_html" ]; then
      echo "current dir is my dir"
   fi
   builtin cd "$1"
}
УВВ
источник
Ох, это выглядит интересно. Я добавил это в свой .bash_profile и добавил echo "Testing..."чуть выше вывода if, но ничего. Нужно ли что-то делать, чтобы применить эти изменения?
TMH
@TomHart Если вы не начали новую сессию, вам нужно будет вставить файл в текущую сессию. ~/.bash_profile
UVV
@ TomTart, похоже, нет /bin/cdв моем CentOS, так что это решение может не сработать
UVV
Я только что заметил это сейчас. Я нашел этот вопрос, в котором говорится, почему unix.stackexchange.com/questions/116955/where-is-cd-located . Тем не менее, хорошее решение для системы, которая на самом деле имеет / bin / cd, хотя :).
TMH
1
Не работает, если вы cd -P public_htmlили cd ~/public_htmlили имеет неожиданное поведение, если вы не можете cdв public_html.
Стефан Шазелас
17

С kshили bash(или zsh):

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

С zsh:

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

( chpwdЭто крючок функция, которая вызывается всякий раз , когда текущий рабочий каталог изменяется (по пути cd, pushd, popd...)).

Стефан Шазелас
источник
3

Обтекание cd, существующая команда, не рекомендуется.

Более универсальным решением было бы определение пользовательского chpwdхука в Bash. (В соответствии с тегами этого вопроса, я предполагаю, что вы используете Bash)

По сравнению с другими современными оболочками в Bash нет полной системы крючков. PROMPT_COMMANDПеременная используется как функция ловушки, которая эквивалентна precmdловушке в ZSH, fish_promptв Fish. В настоящее время ZSH является единственной из известных мне оболочек, в которой есть chpwdвстроенный хук.

PROMPT_COMMAND

Если установлено, значение интерпретируется как команда, выполняемая перед печатью каждого основного приглашения ($ PS1).

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

chpwd Крюк в Баш

Предусмотрен трюк для настройки chpwdэквивалентного хука в Bash на основе 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}"

Поскольку мы обнаружение PWDизменения непосредственно, решение работает с cd, pushdи popd.

Примечание . Основное различие между нашей chpwdреализацией в Bash и chpwdв ZSH заключается в том, что PROMPT_COMMANDона не поддерживается в неинтерактивной оболочке Bash.

Применение

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

Источник: Создать chvwd Equivalent Hook in Bash из моей сущности.

Для всех, кто хочет получить ответ для ZSH. Используйте chpwdкрючок в ZSH. Не определяйте chpwd()функцию напрямую. Более подробно здесь .

Simba
источник
1

Я не эксперт по bash, но я бы взял ответ @ UVV и немного изменил бы его, чтобы он сделал это:

  • вместо проверки public_html, я бы просто проверить какой - то hook-scriptфайл в целевой директории $1, скажем, cd_hook.sh.
  • если это hook-scriptсуществует, запустите его и продолжайте сcd

Это кажется более общим, потому что тогда вы сможете применить cd-hook к любому каталогу, если захотите, просто добавив cd_hook.shв указанный каталог.

выплавляемым и обретенный
источник
3
Это кажется общим, но вы вводите уязвимость безопасности. Кому-то или чему-то нужно только внедрить скрипт-хук в / tmp, например, чтобы заставить вас запускать любой код в следующий раз, когда вы перейдете туда. Вы бы хотели, по крайней мере, убедиться, что хук-скрипт принадлежит вам, а не символической ссылке, не может быть записан никем, кроме вас, что каталог, в котором он находится, доступен для записи только вам ... См. Ведение истории для каждого рабочего каталога (ср. на сеанс оболочки) для более безопасного подхода.
Стефан Шазелас
Спасибо за понимание безопасности @ StéphaneChazelas. Я должен признать, что я даже не думал об этом.
потерян и найден
Я нашел этот вопрос, когда делал именно это: если я cdгде-нибудь, проверю .bashcdфайл и запускаю его, если он существует.
DarkWiiPlayer
0

Используя мощный подход Zsh в Bash:

Сначала простой способ расширить 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
}

Включить в .bashrc:

. ~/.run_scripts

run_scripts ~/.bashrc.d

Вы можете создать ~ / .bashrc.d / cdhook с помощью:

#!/bin/bash

chpwd() {
  : #no action
}

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

Теперь вам нужно заменить функцию:

#list files after cd
chpwd() {
  ls -lah --color
}
albfan
источник