向终端中的命令添加新的运行时标志/选项?

向终端中的命令添加新的运行时标志/选项?

我正在尝试弄清楚如何向从终端运行的命令添加新的运行时标志。

例如:我最近开始尝试使用 Docker,发现通过复制粘贴 ID 来清理已退出的容器非常繁琐。我想cleandocker运行时添加一个命令行选项,这样当我运行时docker clean(或者如果docker --clean我们这样做的话),我可以在内部将其映射到运行带有 docker 运行时已支持的选项的清理命令(即docker rm $(docker ps -a -q -f status=exited))是否可以建立这样的映射?

我知道一种选择是使用别名,但是据我所知,别名不允许在别名中使用空格/命令行标志。同样,shell 函数也没有帮助,因为它们会覆盖整个功能(或者我可能做错了)。我想探索这种可能性已经有一段时间了,所以任何帮助都会很感激。

答案1

您可以定义一个与可执行文件同名的 bash 函数,并让其处理您的附加参数并使用command内置函数明确地调用原始函数。来自man bash

command [-pVv] command [arg ...]
       Run  command  with  args  suppressing  the normal shell function
       lookup. Only builtin commands or commands found in the PATH  are
       executed.

为了显示,

function ls() { 
  case "$1" in 
    "foo")  shift
            echo "do new thing with remaining args: $@" 
            ;; 
    *)      command ls "$@"
            ;;
  esac
}

然后

$ ls -ltr --color=always
total 12
drwxrwxr-x 2 steeldriver steeldriver 4096 Sep 17 08:16 subdir1
drwxrwxr-x 2 steeldriver steeldriver 4096 Sep 17 08:17 subdir2
drwxrwxr-x 2 steeldriver steeldriver 4096 Sep 17 08:17 subdir3

正常工作,而

$ ls foo -ltr --color=always
do new thing with remaining args: -ltr --color=always

(您可能需要unaliasls命令才能尝试这一点)。

显然,现实世界的实现应该进行适当的错误检查——也许用来getopts处理整个命令行而不是简单的 switch/case $1


或者(更传统的方式),你可以通过编写一个包装脚本并将其放置在$PATH比原始可执行文件更早的位置(例如/usr/local/bin$HOME/bin)。在包装器中,通过其绝对路径引用原始可执行文件。

相关内容