我可以插入cd命令吗?


9

我试图在我运行的服务器上进行设置,每当我cdpublic_html95%的时间进入文件夹时,总会运行一些命令来检查某些内容。

无论如何,我都可以挂入,cd所以如果目录是a public_html,它将为我自动运行命令?

如果我无法使用cd命令,是否还有其他事情可以实现,以达到所需的结果?

我正在运行CentOS 5.8。

Answers:


12

您可以将此功能添加到您的.bashrc启动文件或其他启动文件中(取决于您的外壳)。

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

哦,这看起来很有趣。我已将其添加到我的.bash_profile中,并echo "Testing..."在if之上添加了一个,但没有输出。我需要做一些事情来应用这些更改吗?
TMH 2014年

@TomHart如果没有启动一个新的会话,那么你必须通过文件源到当前会话. ~/.bash_profile
UVV

@TomHart似乎没有/bin/cd在我的CentOS的,所以这种解决方案可能行不通
UVV

我刚刚注意到了。我发现了这个问题,它说明了为什么unix.stackexchange.com/questions/116955/where-is-cd-located。对于实际上具有/ bin / cd的系统来说,仍然是一个不错的解决方案:)。
TMH 2014年

1
如果您无法正常工作,cd -P public_html或者cd ~/public_html如果您无法cd进入,则有意外行为public_html
斯特凡Chazelas

17

使用kshbash(或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是一个钩子被称为每当当前工作目录的变化(由单向函数cdpushdpopd...))。


3

cd不建议包装现有命令。

一个更通用的解决方案是chpwd在Bash中定义一个自定义钩子。(根据这个问题的标签,我假设您正在使用Bash)

与其他现代shell相比,Bash中没有完整的挂钩系统。PROMPT_COMMAND变量用作挂钩函数,等效于Fish precmd中ZSH fish_prompt中的挂钩。目前,ZSH是我所知道的唯一具有chpwd内置挂钩的shell。

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直接更改,该解决方案可与cdpushdpopd

注意:非交互式Bash shell不支持chpwdBash和chpwdZSH中实现的主要区别PROMPT_COMMAND

用法

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

资料来源:从我的要旨中在Bash中创建chpwd等效钩子

任何人都想要ZSH的答案。chpwd在ZSH中使用钩子。不要chpwd()直接定义功能。 这里有更多细节


1

我不是bash专家,但我会采用@UVV的答案并对其进行一些修改,以便做到这一点:

  • 不是检查public_html,我只是检查一些hook-script在目标目录文件$1,说cd_hook.sh
  • 如果hook-script存在,请运行它,然后继续cd

这似乎更通用,因为您可以选择将cd-hook应用于任何目录,只需cd_hook.sh在上述目录中添加一个即可。


3
似乎是通用的,但您要引入一个安全漏洞。例如,某人或某物仅需要在/ tmp中插入一个钩子脚本,以使您下次在cd上运行任何代码。您至少要确保该钩子脚本属于您所有,而不是符号链接,除了您之外其他任何人都不能写,其所在目录只能由您写...请参阅按工作目录保存历史记录(请参阅每个shell会话)以获取更安全的方法。
斯特凡Chazelas

感谢您的安全见解@StéphaneChazelas。我不得不承认我什至没有考虑过。
失物招

我这样做时发现了这个问题:如果我在cd某个地方,请检查.bashcd文件并运行它(如果存在)。
DarkWiiPlayer

0

在bash中使用强大的zsh方法:

首先是扩展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
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.