2012-09-27 74 views
0

有時候,我碰巧在執行某些命令,只是後來我意識到我發送了錯誤的參數給一個命令(比如重啓一個Heroku應用程序)。我想以這樣的方式修改bash,如果它看到包含某個字符串的命令,它會提示我我是否確定。例如(想象中的字符串是騰邦):如何攔截包含特定字符串的命令?

$ heroku restart --app tempus 

現在,我想的bash提示我一個Y/N提示,如果我鍵入y,才把我想它執行命令。如果我輸入N,命令將不會被執行。我怎麼能處理這個問題?

回答

1

最簡單的方法是用腳本替換heroku,該腳本在執行真正的heroku之前執行檢查。另一種方法是爲heroku添加一個bash別名。

3

我不知道有任何方法來攔截所有的bash命令,但是你可以使用下面的技巧攔截預定的命令。

  1. 創建一個目錄(比如~/interception),把它作爲$PATH
  2. 中的第一項與要攔截和命令的列表的完整路徑的實際命令創建在該目錄下面的腳本

    [bash]$ cat intercept.sh 
    #!/bin/bash 
    
    # map commands to full path 
    declare -A COMMANDS 
    COMMANDS[heroku]=/usr/bin/heroku 
    COMMANDS[grep]=/bin/grep 
    # ... more ... 
    
    CMD=$(basename $0) # command used to call this script 
    
    if [[ ! -z "${COMMANDS[$CMD]+x}" ]]; then # mapping found 
        # Do what you wish here. You can even modify/inspect the params. 
        echo "intercepted $CMD command... " 
    
        ${COMMANDS[$CMD]} [email protected] # run actual command with all params 
    else 
        echo "Unknown command $CMD" 
    fi 
    
  3. 在同一目錄下,創建使用您想攔截

    命令的名稱符號鏈接到該腳本

現在,每次調用該命令時,都會通過符號鏈接調用該腳本,然後在調用實際命令之前執行您的出價。

您可以通過從配置文件中獲取$COMMANDS來進一步擴展此功能,並創建幫助程序命令以擴充配置文件並創建/刪除sym鏈接。然後,您可以使用以下命令管理誰設置:

intercept_add `which heroku` 
intercept_remove heroku 
intercept_list 
2

因爲bash本身不支持命令行篩選器,所以不可能攔截命令。

這裏是一個骯髒的解決方案:

  1. 查找路徑上的所有可執行文件,併爲他們每個人創建包裝功能。
  2. 如果聲明瞭包裝函數,則函數會調用prefilter()函數。
  3. 如果prefilter()功能失敗,則該命令被取消。

SOURCE:cmd-wrap。SH

#!/bin/bash # The shebang is only useful for debug. Don't execute this script. 

function create_wrapper() { 
    local exe="$1" 
    local name="${exe##*/}" 

    # Only create wrappers for non-builtin commands 
    [ `type -t "$name"` = 'file' ] || return 

    # echo "Create command wrapper for $exe" 
    eval " 
    function $name() {\ 
     if [ \"\$(type -t prefilter)\" = 'function' ]; then \ 
      prefilter \"$name\" \"\[email protected]\" || return; \ 
     fi; \ 
     $exe \"\[email protected]\"; 
    }" 
} 
# It's also possible to add pre/post hookers by install 
# [ `type -t \"$name-pre\"` = 'function' ] && \"$name-pre\" \"\[email protected]\" 
# into the dynamic generated function body. 

function _create_wrappers() { 
    local paths="$PATH" 
    local path 
    local f n 

    while [ -n "$paths" ]; do 
     path="${paths%%:*}" 
     if [ "$path" = "$paths" ]; then 
      paths= 
     else 
      paths="${paths#*:}" 
     fi 

     # For each path element: 
     for f in "$path"/*; do 
      if [ -x "$f" ]; then 
       # Don't create wrapper for strange command names. 
       n="${f##*/}" 
       [ -n "${n//[a-zA-Z_-]/}" ] || create_wrapper "$f" 
      fi 
     done 
    done 

    unset _create_wrappers # Remove the installer. 
    unset create_wrapper # Remove the helper fn, which isn't used anymore. 
} 

_create_wrappers 

利用它爲您的問題:

  1. 源它在bash:

    . ./cmd-wrap.sh 
    
  2. 創建您的prefilter()版本檢查,如果任何參數包含字符串:

    function prefilter() { 
        local a y 
        for a in "[email protected]"; do 
         if [ "$a" != "${a/tempus}" ]; then 
          echo -n "WARNING: The command contains tempus. Continue?" 
          read y 
          [ "$y" = 'Y' ] || [ "$y" = 'y' ] 
          return $? 
         fi 
        done 
        return 0 
    } 
    
  3. 運行

    heroku restart --app tempus 
    

    但不

    /usr/bin/heroku restart --app tempus 
    

    利用包裝功能。

2

最簡單的方法是使用別名。這個簡單的例子應該爲你工作:

這可以防止在將這個代碼到你的bash配置文件〜/ .profile文件,然後註銷並重新登錄參數

function protect_heroku { 
    # use grep to determine if the bad string is in arguments 
    echo "$*" | grep tempus > /dev/null 
    # if string is not in arguments 
    if [ $? != 0 ]; then 
     # run the protected command using its full path, so as not to trigger alias 
     /path/to/heroku "[email protected]" 
    else 
     # get user confirmation 
     echo -n Are you sure \(y/n\)?' ' 
     read CONFIRM 
     if [ "$CONFIRM" = y ]; then 
      # run the protected command using its full path 
      /path/to/heroku "[email protected]" 
     fi 
    fi 
} 

# This is the key: 
# This alias command means that 'heroku' from now refers 
# to the function protect_heroku, rather than /bin/heroku 
alias heroku=protect_heroku 

與騰邦執行Heroku的命令從現在開始,bash將會保護你免於意外地用tempus運行heroku。

相關問題