Bashで2つのコマンドを置き換える方法は?

Bashで2つのコマンドを置き換える方法は?

コマンドAとコマンドがありますが、入力したとおりに実行したいBとし、その逆の場合も同じだとしましょう。頑張ったBA

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

しかし、これは何らかの理由で動作しないようです。

どうすればいいですか?

編集する:

コマンドは実際にはmyBで関数として定義されているので.bashrc

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

提案どおりに動作しません。

私はthisを指定するように質問を更新するか、bashで定義された関数であると思いましAB

答え1

したがって、シェルがコマンドを検索する方法を明示的に確認する方法はいくつかあります。あなたはそれを使用することができます...

command command_name

...シェルに呼び出しのみを指示します。コマンド名$PATH実行可能ファイルの場合。これはあなたのような場合に重要です。なぜなら、作業が完了すると通常、拡張が繰り返しを止めるまでに20回かかりalias A始めたalias Bところに戻るからです。呼び出されたときにのみd実行可能ファイルを呼び出し、その逆も同様であれば、次のようにすることができます。alias Aalias$PATHBA

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

A...これは、名前付き関数を呼び出すことを避けるべきですB。それ以外の場合 - シェルは参照を拡張しませんが、aliasまだalias関数を呼び出すためです。コマンド名引用するには、例えば定義から引用することがAできます。B

alias A=\\B B=\\A

いいですね。これは20回繰り返されません。どこかでこの記事を読んだと誓うかもしれませんが、man少なくとも両方は本当bashではないようです。ksh (今までそのうちの1つだけをテストしました)。実際には2回だけ繰り返されます。

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

これは、シェルが関数名をエイリアスの内容に置き換えることを意味します。これは通常、拡張が発生すると予想される場所ではありませんechoまだ関数をオーバーライドして実行します。

関連情報