展开执行另一个别名的别名(嵌套别名)

时间:2018-04-27 22:52:17

标签: bash macos terminal

我有两个别名:

alias ls="ls -G"
alias la="ls -aFhlT"

我知道在您输入别名后,但在执行之前,您可以输入 Meta - Control - e (可能是 Alt - Control - e ,但可能 Esc - Control - e < / kbd>)扩展你输入的内容。

所以,如果我使用这种方法扩展我的别名la,我得到:

ls -aFhlT

然而,我真正想要的是:

ls -G -aFhlT

除了第二次输入 Meta - Control - e 之外,还有什么办法可以实现吗?

- 或 -

有没有办法确认我执行la实际执行ls -G -aFhlT(除了知道嵌套别名是如何工作的,并相信它做了我认为它做了什么)?

我正在尝试在macOS上执行此操作,但也会接受一般的bash解决方案。

1 个答案:

答案 0 :(得分:0)

这个问题在使用别名和使用函数之间存在细微差别。当别名变得稍微复杂时,通常更好的是编写函数。话虽这么说,我 找到了这个问题的解决方案,允许根据需要扩展别名。

我为此写了一个bash函数:

xtrace() {
    local eval_cmd
    printf -v eval_cmd '%q' "${@}"
    { set -x
      eval "${eval_cmd}"
    } 2>&1 | grep '^++'
    return "${PIPESTATUS[0]}"
}

-v的{​​{1}}标记会将printf的输出存储在指定的变量中。

printf格式字符串printf将打印关联的参数(在这种情况下为%q shell-quoted ,可重复使用作为输入。这消除了将任意代码/命令传递给$@所带来的危险。

然后我使用命令组eval,因此我可以控制{ ... }的功能,它告诉bash打印所有已执行命令的跟踪。出于我的目的,除了完全展开的命令之外,我不关心任何输出,因此我将set -xstderr重定向到以“++”开头的输出行。这将是显示完全展开的命令的行。

最后,我返回grep的值,其中包含在命令组中执行的 last 命令的返回码(即PIPESTATUS[0]命令)。

因此,我们将得到如下内容:

eval

非常感谢@CharlesDuffy提出$ xtrace la; echo $? ++ ls -G -aFhlT 0 建议以及set -x的输入卫生。