这是我的.zshrc
:
alias inst="adb install -r -d"
notify() {
start=$(date +%s)
"$@"
notify-send "\"$(echo $@)\" took $(($(date +%s) - start)) seconds to finish"
}
当我运行命令notify inst app.apk
时,出现错误:
notify:2: command not found: inst
0.00s user 0.00s system 0% cpu 0.001 total
任何人都可以解释为什么这不起作用,并希望有办法让它发挥作用吗?
答案 0 :(得分:2)
当shell处理命令时(例如PATH
搜索),它将检查第一个标记/参数(空格分隔)是否属于加载在其中的别名当前的环境。如果您尝试替换的别名不是第一个令牌,则不会进行替换。如果您的别名恰好不是PATH
或当前目录中的可执行文件的名称,则错误将传播回command not found
。
由于您的问题是关于Z Shell,zsh
实际上提供了一个鲜为人知的称为全局别名的功能。如果使用-g
标记声明了别名,zsh
将不仅对第一个标记进行适当的替换,而是对任何标记进行适当的替换,无论顺序如何。
alias -g inst="adb install -r -d"
应该可以解决问题。
请注意,出于可移植性原因,这只是一个zsh
功能,并确保您编写的任何脚本都有一个调用zsh
shell的shebang行:#!/usr/bin/env zsh
我还建议不要在重要或生产脚本中使用zsh
全局别名。对于个人使用,它非常好。
答案 1 :(得分:0)
首先,根据the advanced bash scripting guide:
在脚本中,别名的用途非常有限。
所以你可以考虑不使用别名而是使用一个函数(仍然来自同一页面,下面是2段):
几乎无一例外,无论我们想要做什么别名,都可以通过函数更有效地完成。
如果这是为您自己使用.zshrc
中的别名的快速脚本,那么仍然有一条出路。
alias foo='echo hello'
bar() {
`alias "$@" | cut -d\' -f2`
}
bar foo # => hello
检查每个简单命令的第一个单词(如果不加引号),以查看它是否有别名。如果是这样,该单词将被别名的文本替换。别名和替换文本可以包含任何有效的shell输入,包括shell元字符,但别名不能包含`='。
替换文本的第一个单词是针对别名进行测试的,但是与扩展的别名相同的单词不会再次展开。这意味着,例如,可以将ls别名为“ls -F”,而Bash不会尝试以递归方式扩展替换文本。
当shell不是交互式时,不会扩展别名,除非使用shopt设置了expand_aliases shell选项。
关于别名的定义和使用的规则有些令人困惑。在执行该行上的任何命令之前,Bash始终会读取至少一个完整的输入行。读取命令时会扩展别名,而不会在执行时扩展别名。因此,在读取下一行输入之前,与另一个命令出现在同一行上的别名定义不会生效。该行上别名定义后面的命令不受新别名的影响。执行函数时,此行为也是一个问题。 在读取函数定义时扩展别名,而不是在执行函数时扩展别名,因为函数定义本身就是复合命令。因此,在执行该函数之后,函数中定义的别名才可用。为安全起见,请始终将别名定义放在单独的行中,并且不要在复合命令中使用别名。