2011-04-08 60 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 

}