抱歉,标题不好。我实在想不出更好的了。
我想将一个命令别名为另一个命令,并从命令本身的文本中提取选项。我意识到这不清楚,所以也许一个例子会有所帮助:
如果我要用 做这样的事情ls
,我希望能够使用以下别名:
ll -> ls -l
la -> ls -a
lal -> ls -al
l -> ls
但
ls -> ls #allow this special case to not change
最好的情况下,我希望能够自己决定是否忽略部分命令,就像我对 in 所做的那样s
。ls
因此,例如,我还希望能够使用 grep 来执行此操作:
grepi -> grep -i
greps -> grep -s
grepis -> grep -is
我们现在不必担心带参数的选项,例如,如果grepm
失败也没关系。
答案1
您可以使用以下命令执行此操作:
- 设置
shopt extdebug
,启用多个调试选项。相关的选项是:如果 DEBUG 陷阱运行的命令返回非零值,则会跳过并且不执行下一个命令。我们需要这个才能不真正尝试执行未定义的lal
命令。 - 为
trap
信号DEBUG
,在执行任何命令之前执行。设置陷阱如下:trap 'insane_magic_alias' DEBUG
。
该函数insane_magic_alias
解析将要执行的命令(在 中$BASH_COMMAND
)并对其进行处理,通过 中止执行过程中实际输入的命令return 1
,除非type
说它存在,在这种情况下我们什么也不做(并让它运行)。
# make sure to name this function appropriately...
function insane_magic_alias {
local CMD=$BASH_COMMAND
# make sure this isn't a command that exists
if ! type "$( echo "$CMD" | awk -F' ' '{ print $1 }' )" >/dev/null 2>&1 ; then
# handle calls to `l*`
if [[ ${#CMD} -gt 1 && "${CMD:0:1}" = l ]] ; then
# actual transformed program call
ls -${CMD:1}
# abort execution of undefined command
return 1
fi
fi
# either execute an existing command, or show the "command not found" message
return 0
}
结果:
$ lal
total 0
drwxr-xr-x 2 danielbeck staff 68 2 Aug 22:53 .
drwxr-xr-x@ 78 danielbeck staff 2652 2 Aug 22:53 ..
请注意,您的 bash 认为您刚刚运行了一个作业(如果您在 中打印作业信息PROMPT_COMMAND
,您会注意到这一点)。另外,可能还有其他一些副作用导致此操作失败,而不仅仅是一个简单的演示...