如何在 bash 中交换两个命令?

如何在 bash 中交换两个命令?

假设我有命令A和命令B,但我想B在键入时运行A,反之亦然。我试过了

alias A='B'
alias B='A'

但这似乎由于某种原因不起作用。

我该怎么做呢?

编辑:

CommandB实际上已被定义为 my 中的函数.bashrc,所以

alias A='command B'
alias B='command A'

不按建议工作。

我想我可以更新问题来说明这一点A,也B可以是 bash 中定义的函数。

答案1

因此,您可以通过几种不同的方式明确了解 shell 定位命令的方式。您可以使用...

command command_name

...指示 shell 仅调用命令名如果它是$PATHd 可执行文件。这在像您这样的情况下很重要,因为当您完成时alias A指的alias Balias A通常指在扩展停止递归之前 20 次alias- 并且您会回到开始的地方。如果你想在调用时绝对只调用$PATHd 可执行文件,反之亦然,你可以这样做......BA

alias A='command B' B='command A'

...这应该避免调用名为A或 的函数B。否则 - 因为 shell 不会将引用扩展alias为 analias但仍会调用函数,即使其命令名被引用,你可以引用AB在定义中,例如......

alias A=\\B B=\\A

好的,所以它不会递归二十次。我可以发誓我在某个页面上读到过这一点man,但我想至少这两者都不是bash真的ksh (到目前为止只测试了其中一个)。事实上,它只递归两次:

n=0
A(){ echo not B; n=0; }
B(){ echo not A; n=0; }
alias A='echo "$((n+=1))";B' B='echo "$((n+=1))";A'

如果我执行上述操作并执行...

A

...bash其中打印:

1
2
not B

我想这与手册中的内容相关bash

  • 替换文本的第一个单词会进行别名测试,但与正在扩展的别名相同的单词不会再次扩展。例如,这意味着可以别名ls为,并且不会尝试递归地扩展替换文本。ls -Fbash

我之前读过,但我认为这样做时它不会测试导致当前扩展的所有扩展 - 我认为它只适用于链中的最新扩展。无论如何,这似乎就是原因。

不过,我确实注意到了一些有趣的行为。在我声明了别名和函数之后,我重新运行命令,但中间的空白少了一些 - 像这样:

A(){ echo not B; }; B(){ echo not A; }; A; B

...这确实...

1
2
3
4
5
6
not B
7
8
not A

这意味着 shell 用别名内容替换了函数名 - 这不是人们通常期望发生扩展的位置 - secho仍然重新定义然后执行函数。

相关内容