2011-04-08 61 views
3

我用rvm和bundler对我的所有项目进行了沙箱处理,因此它们都很好地独立,并且所有依赖项都可以保存在源代码管理中。在其中的一个中,我使用保存在/ bin文件夹中的bin来运行项目。因此我需要将其添加到PATH变量中。但是,我想要在项目路径中的文件中完成,因此它会自动完成。如何在转到目录时自动运行bash脚本?

这里是我的脚本,它是在一个名为“.runme”文件:

# .runme 
# add local bin folder to PATH unless it's already in there 
function __bin_dir { 
    echo "`pwd`/bin" 
} 
function __have_bin { 
    echo $PATH | grep "^$(__bin_dir)" 
} 
[ "$(__have_bin)" == "" ] && export PATH=$(__bin_dir):$PATH 

我能得到这个要去它在文件夹中自动运行?

+0

想让“.runme”脚本在有人向目录中执行“cd”时自动运行? – 2011-04-08 11:34:19

+0

是的,这是可能的吗? – 2011-04-08 11:39:50

回答

3

如果您可以向需要此功能的每个用户的.bashrc文件添加内容,则可能需要挂钩cd操作以检查您需要的内容。

有一个关于如何挂钩到cd操作的另一个SO问题:Is there a hook in Bash to find out when the cwd changes?

我不熟悉的RVM,但他们似乎对挂接到cd一些文档:https://rvm.beginrescueend.com/workflow/hooks/

+0

感谢Kannan-- after_cd hook看起来很有希望。一个问题是,无论我放在哪里的任何代码都会在有人cd到任何文件夹时运行,而不仅仅是项目文件夹,所以我需要添加某种测试以确保它只发生在项目文件夹中。我现在正在向非自动化的方向摇摆,而是在项目根目录中的一些明显的安装脚本中。 – 2011-04-08 12:53:24

+0

你可以制作一个脚本,输入最小的名字,当你进入你的新目录时,输入't'(或其他),t脚本可以看到它是否在一个感兴趣的目录中,如果是,然后执行一些代码。祝你好运。 – shellter 2011-04-08 17:26:31

+0

是的,你需要添加一个测试(检查当前目录中是否有“.runme”文件,如果有的话,运行它)。但总的来说,我宁愿不自动。 – 2011-04-12 06:29:30

1

另一个窍门是把功能在你的PS1,像

export PS1='...\[$(.runme)\] 

(不管你人更换...准备好在你的PS1中)。这将在每个新提示中运行检查。

但是,您希望尽可能快地运行该命令,因为它的运行时将延迟显示提示。一个好的开始是使它成为一个bash函数,并且只使用bash内建函数,因此它不必fork来运行任何外部程序(如grep)。

+1

虽然有效,但使用Bash的'$ PROMPT_COMMAND'变量可能更清晰:“如果设置,则该值被解释为在打印每个主要提示($ PS1)之前执行的命令。” - http://www.gnu.org/software/bash/manual/html_node/Bash-Variables.html – mklement0 2015-06-10 14:53:43

1

这里有一个简单的别名的方式侵扰程度较低的替代方案:

alias lx='PATH="./bin:$PATH"' 

然后,您可以使用lx大号 OCALËX ecution)任何文件夹中,有一个bin子目录执行脚本没有路径;例如,从当前目录执行脚本./bin/start-server,运行:

lx start-server 

如果要启用基于对本地可执行制表完成,以下内容添加到您的bash配置文件(测试在OSX和Linux上):

# Install the custom tab-completion function defined below. 
complete -F _complete_lx -- lx 


# Command-completion function for lx: tab-completes the executables in 
# the ./bin subfolder. 
_complete_lx() { 

    # Set the directory in which to look for local executables. 
    local localExeDir='./bin' 

     # Get the current command-line token. 
    local token=${COMP_WORDS[$COMP_CWORD]} 
    local tokenLen=${#token} 

    # Find all local executables. 
    read -d ' ' -ra localExes < <(find "$localExeDir" -maxdepth 1 -type f -perm -a=x -exec basename -a {} +;) 

    # Filter the list of local executables 
    # based on the current command-line token. 

    # Turn case-insensitive matching temporarily on, if necessary. 
    local nocasematchWasOff=0 
    shopt nocasematch >/dev/null || nocasematchWasOff=1 
    ((nocasematchWasOff)) && shopt -s nocasematch 

    COMPREPLY=() 
    for localExe in "${localExes[@]}"; do 
    if [[ ${localExe:0:$((tokenLen))} == "$token" ]]; then 
     COMPREPLY+=("$localExe") 
    fi 
    done 

    # Restore state of 'nocasematch' option, if necessary. 
    ((nocasematchWasOff)) && shopt -u nocasematch 

}