有時候,我碰巧在執行某些命令,只是後來我意識到我發送了錯誤的參數給一個命令(比如重啓一個Heroku應用程序)。我想以這樣的方式修改bash,如果它看到包含某個字符串的命令,它會提示我我是否確定。例如(想象中的字符串是騰邦):如何攔截包含特定字符串的命令?
$ heroku restart --app tempus
現在,我想的bash提示我一個Y/N提示,如果我鍵入y
,才把我想它執行命令。如果我輸入N,命令將不會被執行。我怎麼能處理這個問題?
有時候,我碰巧在執行某些命令,只是後來我意識到我發送了錯誤的參數給一個命令(比如重啓一個Heroku應用程序)。我想以這樣的方式修改bash,如果它看到包含某個字符串的命令,它會提示我我是否確定。例如(想象中的字符串是騰邦):如何攔截包含特定字符串的命令?
$ heroku restart --app tempus
現在,我想的bash提示我一個Y/N提示,如果我鍵入y
,才把我想它執行命令。如果我輸入N,命令將不會被執行。我怎麼能處理這個問題?
最簡單的方法是用腳本替換heroku
,該腳本在執行真正的heroku之前執行檢查。另一種方法是爲heroku
添加一個bash別名。
我不知道有任何方法來攔截所有的bash命令,但是你可以使用下面的技巧攔截預定的命令。
~/interception
),把它作爲$PATH
中的第一項與要攔截和命令的列表的完整路徑的實際命令創建在該目錄下面的腳本
[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
在同一目錄下,創建使用您想攔截
命令的名稱符號鏈接到該腳本現在,每次調用該命令時,都會通過符號鏈接調用該腳本,然後在調用實際命令之前執行您的出價。
您可以通過從配置文件中獲取$COMMANDS
來進一步擴展此功能,並創建幫助程序命令以擴充配置文件並創建/刪除sym鏈接。然後,您可以使用以下命令管理誰設置:
intercept_add `which heroku`
intercept_remove heroku
intercept_list
因爲bash本身不支持命令行篩選器,所以不可能攔截命令。
這裏是一個骯髒的解決方案:
prefilter()
函數。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
利用它爲您的問題:
源它在bash:
. ./cmd-wrap.sh
創建您的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
}
運行
heroku restart --app tempus
但不
/usr/bin/heroku restart --app tempus
利用包裝功能。
最簡單的方法是使用別名。這個簡單的例子應該爲你工作:
這可以防止在將這個代碼到你的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。