有时候,我发现我正在执行某些命令,之后才意识到我向命令发送了错误的参数(比如重新启动Heroku应用程序)。我想以这样的方式修改bash:如果它看到包含某个字符串的命令,它会提示我是否确定。例如(想象一下字符串是tempus):
$ heroku restart --app tempus
现在,我希望bash用Y / N提示符提示我,如果我输入y
,我只希望它执行命令。如果我键入N,则不会执行该命令。我怎么能处理这个问题?
答案 0 :(得分:3)
我不知道拦截所有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]} $@ # run actual command with all params
else
echo "Unknown command $CMD"
fi
在同一目录中,使用您要拦截的命令名称为该脚本创建符号链接
[bash]$ ln -s intercept.sh grep
[bash]$ ln -s intercept.sh heroku
现在,每次调用该命令时,都会通过符号链接调用该脚本,然后它可以在调用实际命令之前进行出价。
您可以通过从配置文件中获取$COMMANDS
来进一步扩展它,并创建帮助程序命令以扩充配置文件并创建/删除sym链接。然后,您可以使用以下命令管理who设置:
intercept_add `which heroku`
intercept_remove heroku
intercept_list
答案 1 :(得分:2)
由于bash本身不支持命令行过滤器,因此无法拦截命令。
这是一个肮脏的解决方案:
prefilter()
函数。prefilter()
功能失败,则取消该命令。消息来源: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\" \"\$@\" || return; \
fi; \
$exe \"\$@\";
}"
}
# It's also possible to add pre/post hookers by install
# [ `type -t \"$name-pre\"` = 'function' ] && \"$name-pre\" \"\$@\"
# 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 "$@"; 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
使用包装函数。
答案 2 :(得分:2)
最简单的方法是使用别名。这个简单的例子适合你:
这可以防止在参数
中使用tempus执行heroku命令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 "$@"
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 "$@"
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
将此代码放入您的bash配置文件〜/ .profile中,然后注销并重新登录。从现在开始,bash将保护您免于意外地使用tempus运行heroku。
答案 3 :(得分:1)
最简单的方法是在执行真正的heroku之前用执行检查的脚本替换heroku
。另一种方法是为heroku
添加bash别名。