对于上下文,我使用 zsh。每次我使用 时locate
,我都想传递-i
和-A
标志。
通常,如果我可以逃脱它,我会创建一个alias
与现有命令同名的命令来执行此操作。但根据这个问题,别名不能接受参数,所以我必须使用函数代替。通常我会停在那里,因为我觉得函数与命令同名的想法是错误的,尽管我不能说出原因。
当我终于要创建这样一个函数时,我有了这样的想法:这对我来说是一种常见模式,想要为命令设置默认标志;有更简单的方法吗?也许 zsh 为这个问题提供了更好的解决方案?
这让我想到了另一个想法:覆盖现有命令是否是一种反模式?我一直这样做,因为它允许我跳过脑海中的联想:例如,“为什么没有ll
页面man
?哦,是的:ll
真正的意思是ls -la
。我需要做man ls
,而不是man ll
。等等。”
总结一下:
- 重写可以/惯用吗现有命令有别名/函数吗?
- zsh 或其他一些工具是否提供了更直接的方式来设置特定命令的默认标志?
答案1
我对你提到的另一篇文章感到非常惊讶,因为它可能非常具有误导性。只是因为别名不使用参数并不意味着别名不能放参数。当然,您可以将选项放在别名中,但这只是受限制的,这意味着别名会被替换在一处。
$ alias ls='ls -l'
$ ls
# will run: ls -l
$ ls foo
# will run: ls -l foo
其他问题提出的问题是,如果您想向具有参数的别名添加选项。
所以如果你有一个别名:
$ alias movetotrash='mv ~/Trash'
# no way to use inject anything inside 'mv' and '~/Trash'
所以在你的情况下
$ alias locate='locate -i -A'
# will expand to 'locate -i -A' and then whatever else you type.
至于你的具体问题:
Linux 发行版通过别名附带默认“选项”是很常见的,例如, ls 经常有一个alias ls 'ls --color=auto'
或 用于 root 登录,您可能会看到alias mv 'mv -i'
。因此,它可以被认为是向用户提供更好的默认值并使用与底层二进制文件相同的名称的标准方法。如果用户不想使用别名并且它是在标准环境中设置的,则他们可以使用 unalias 永久取消设置别名,或者在使用反斜杠运行命令时,例如\mv a b
将阻止该执行的别名扩展(如是否使用完整路径,例如 /usr/bin/mv a b
)
我不相信 zsh 在这个领域提供任何额外的功能,当然也没有什么是“标准”的。人们经常编写包装 shell 脚本,有时还编写 shell 函数。但对于普通软件,别名通常是人们使用的解决方案。如果程序足够复杂,通常会获得一个 rc 文件来满足普通用户的喜好。
我认为 popt 库是一个试图让选项变得更容易的工具,它允许用户创建自己的软件选项,但是 popt 库没有被广泛使用,而且我认为它没有能力设置默认值。
答案2
使用相同名称的别名几乎就是别名的全部要点。
An alias definition provides a string value that shall replace a command name when it is encountered
alias grep='grep --ignore-case --color=auto'
可以完美地替代grep
.
创建函数或~/bin/
脚本来替换命令将需要您直接引用该命令。
function grep {
grep --ignore-case --color=auto "${@}"
}
或者
~/bin/grep
:
grep --ignore-case --color=auto "${@}"
...将锁定在递归循环中,其中函数或脚本无休止地调用自身,而...
function grep {
/bin/grep --ignore-case --color=auto "${@}"
}
或者
~/bin/grep
:
/bin/grep --ignore-case --color=auto "${@}"
...不会因递归死亡而死亡,因为它们不调用自己。
别名的唯一问题是您无法在“默认”参数之间内部插入参数。您可以使用函数和脚本...
function grep {
/bin/grep ${1} --ignore-case --color=auto ${2}
}
或者
~/bin/grep
:
/bin/grep ${1} --ignore-case --color=auto ${2}
...但是如果您尝试使用期望正常参数序列的新版本命令,它会很快变得混乱。