![如何在 zsh 中使用别名覆盖多字命令?](https://linux22.com/image/179676/%E5%A6%82%E4%BD%95%E5%9C%A8%20zsh%20%E4%B8%AD%E4%BD%BF%E7%94%A8%E5%88%AB%E5%90%8D%E8%A6%86%E7%9B%96%E5%A4%9A%E5%AD%97%E5%91%BD%E4%BB%A4%EF%BC%9F.png)
我试图docker ps
超越docker ps --format="table {{.ID}} {{.Image}} {{.Status}}"
我读了这个问题和参考文档,但我无法让它工作。
我尝试了一些“编译”的方法,这是最新的尝试。
alias func='dockerps'
function dockerps() {
'docker ps'='docker ps --format="table {{.ID}} {{.Image}} {{.Status}}"'$\
}
如何修复我的代码,以便键入内容时docker ps
保留我的格式?
答案1
不存在多词别名之类的东西。你提到的SO答案对我来说似乎是完全错误的:它没有任何意义,而且我找不到任何可以产生接近预期效果的功能的痕迹,即使在挖掘 zsh 历史记录时也是如此4.3(当时 zsh 的开发版本)中可能存在的实验性功能,该功能在 5.0 发布之前已被删除。您编写的内容具有明确定义的含义:它定义了一个别名func
和一个名为 的函数,因此它仅对第一个单词是or 的dockerps
命令行有效。如果该函数被调用,它会尝试设置一个具有无效名称的变量,这会失败。func
dockerps
Zsh 允许您为包含特殊字符的单词定义别名,例如
darkstar% alias "'docker ps'"='echo docker ps in single quotes'
darkstar% alias 'docker\ ps'='echo docker backslash ps'
darkstar% 'docker ps'
docker ps in single quotes
darkstar% docker\ ps
docker backslash ps
darkstar% "docker ps"
zsh: command not found: docker ps
但这并不是特别有用。'docker ps'
是一个词而是docker ps
两个词。
您必须以正常方式执行此操作:定义一个名为 的函数docker
,并让它分析其参数。这是一个支持全局选项的简单版本,但需要使用--option=value
而不是--option value
用于带有参数的全局选项。
docker () {
setopt local_options extended_glob unset
local -i i=$argv[(i)^-*]
# $argv[i] is the first non-option argument (or empty if there is none).
# See if we want to insert something after it.
case $argv[i] in
ps) argv[i+1,i]=(--format="table {{.ID}} {{.Image}} {{.Status}}");;
esac
command docker "$@"
}
答案2
从技术上讲,就像csh
该alias
错误功能的来源一样,您可以这样做:
alias docker='docker '
alias ps='ps --format="table {{.ID}} {{.Image}} {{.Status}}"'
这将实现你想要的,但这意味着:
- 后面的所有单词
docker
都将受到别名扩展的影响(该alias cmd='cmd '
技巧适用于command
,等命令env
,sudo
这些命令将命令作为参数,因此别名也会在它们之后扩展)。 ps
前面没有的单词也会docker
被扩展,这意味着您无法ps
再运行独立命令,除非您更改调用的措辞(例如"ps" -ef
)。
在这里,我只是定义一个新的命令使用不同的名称,因此它不会与执行您想要的操作的原始名称发生冲突:
my-docker-ps() docker ps --format="table {{.ID}} {{.Image}} {{.Status}}" "$@"
这里作为函数实现,尽管您可能更喜欢将其实现为脚本,因此它也可以在 shell 外部使用。