我正在尝试编写 bash 命令包装器,它将动态修补 bash 当前命令。但我遇到了问题。由于我不是一名优秀的 Shell 用户,我无法在字符串中写出正确的变量赋值表达式。见下文:
我设置了陷阱来预执行,通过这个:
alex@bender:~$ trap "caller >/dev/null || xxx \"\${BASH_COMMAND}"\" DEBUG;
我想改变变量BASH_COMMAND,执行类似 BASH_COMMAND= 的操作,xxx ${BASH_COMMAND}
但我不知道如何在此字符串中转义变量
注意:xxx —— 我的自定义函数,如果位于命令末尾的单词 teststr,则必须返回一些值
function xxx(){
# find by grep, if teststr in the end
`echo "$1" | grep "teststr$" >/dev/null`;
# if true ==> do
if [ "$?" == "0" ]; then
# cut last 6 chars (len('teststr')==6)
var=`echo "$1" | sed 's/......$//'`;
echo "$var";
fi }
我怎样才能做这些事?:
alex@bender:~$ trap "caller >/dev/null || ${BASH_COMMAND}=`xxx $BASH_COMMAND`" DEBUG;
答案1
这是一个可行的解决方案,但它会捕获所有命令,而不仅仅是通过提示输入的命令(因此脚本中的命令也会被捕获)。您可能需要修改它才能得到您想要的结果。
首先,设置shoptextdebug
选项。
来自手动的:
如果设置,则启用供调试器使用的行为:
1- 内置命令 declared 的 -F 选项(参见 Bash Builtins)显示作为参数提供的每个函数名对应的源文件名和行号
。2-如果 DEBUG 陷阱运行的命令返回非零值,则会跳过并且不执行下一个命令。
3- 如果 DEBUG 陷阱运行的命令返回值 2,并且 shell 正在子例程(由 . 或 source 内置命令执行的 shell 函数或 shell 脚本)中执行,则会模拟返回调用。4-
BASH_ARGC 和 BASH_ARGV 按照其描述进行更新(请参阅 Bash 变量)。5-
启用函数跟踪:命令替换、shell 函数和使用(命令)调用的子 shell 将继承 DEBUG 和 RETURN 陷阱。6-
启用错误跟踪:命令替换、shell 函数和使用(命令)调用的子 shell 将继承 ERR 陷阱。
(重点是我的)
您需要此命令来取消执行用户输入的命令并改为调用您的自定义函数。如果未设置,Bash 将调用您的自定义函数和执行用户的命令。
然后,使用简单的引号来编写你的陷阱以防止 Bash 变量扩展:
trap 'caller >/dev/null || xxx $BASH_COMMAND' DEBUG
现在,如果您的xxx
函数返回非零值(例如1
),则用户的命令将不会被执行。
以下是完整示例:
$ shopt -s extdebug
$ xxx() { if [ "$1" = 'sudo' ]; then echo "No sudo, please.";return 1; fi }
$ trap 'caller >/dev/null || xxx $BASH_COMMAND' DEBUG
$ ls
foo bar
$ sudo ls
No sudo, please.
在此示例中,xxx
检查命令的第一个字是否为,如果是,则打印一条消息并取消该命令。您可以使用sudo
获取整个用户命令。xxx
"$*"