如何在 zsh 中使用别名覆盖多字命令?

如何在 zsh 中使用别名覆盖多字命令?

我试图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命令行有效。如果该函数被调用,它会尝试设置一个具有无效名称的变量,这会失败。funcdockerps

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

从技术上讲,就像cshalias错误功能的来源一样,您可以这样做:

alias docker='docker '
alias     ps='ps --format="table {{.ID}} {{.Image}} {{.Status}}"'

这将实现你想要的,但这意味着:

  1. 后面的所有单词docker都将受到别名扩展的影响(该alias cmd='cmd '技巧适用于command,等命令envsudo这些命令将命令作为参数,因此别名也会在它们之后扩展)。
  2. ps前面没有的单词也会docker被扩展,这意味着您无法ps再运行独立命令,除非您更改调用的措辞(例如"ps" -ef)。

在这里,我只是定义一个新的命令使用不同的名称,因此它不会与执行您想要的操作的原始名称发生冲突:

my-docker-ps() docker ps --format="table {{.ID}} {{.Image}} {{.Status}}" "$@"

这里作为函数实现,尽管您可能更喜欢将其实现为脚本,因此它也可以在 shell 外部使用。

相关内容