bashrcでエイリアスを使用中に競合の可能性をテストするにはどうすればよいですか?


12

エイリアスコマンドを含むbashrcの更新によりシステムで発生したすべてのコマンド競合を一覧表示する簡単な方法はありますか?

たとえば、誰かがalias ls=/path/to/user-generated/executablebashrcで書き込みます。これが実際のコマンドをマスクしていることをどのように知ることができますか(ls)。1つの方法は、bashrcのソースの前後にすべてのエイリアスを実行し、出力を比較することです。より良い方法はありますか?

Ubuntu 12.04を実行しています。

bash-バージョン

GNU bash、バージョン4.2.24(1)-release(i686-pc-linux-gnu)


サイドノートとして、bashに固有の質問をするときにOSバージョンではなく、bashのバージョンを提供する方が回答する方が一般的に便利です。
ヨルダン

@jordanmが更新されました。
user13107

回答:


8

エイリアスによってマスクされているコマンドを確認するには、次のようにします。

alias | sed 's/^[^ ]* *\|=.*$//g' | while read a; do
  printf "%20.20s : %s\n" $a "$(type -ta $a | tr '\n' ' ')"
done | awk -F: '$2 ~ /file/'

説明

alias定義されたエイリアスのみをリストしsed、その名前を抽出します。whileループはtype -taそれぞれに対して実行されawk、エイリアスとファイルの両方を含む行を出力します。


15

typeコマンドをbashがどのように解釈するかを調べるために使用できます。


たとえば、ここにtype ls印刷しls is aliased to `ls --color=auto'ます。
l0b0

同じはで動作しますがwhich、両方の(タイプ、どちらの)シェル組み込みが同じである場合、私は今はしません。
数学

@math:をtype which伝えるwhich is /usr/bin/whichため、組み込みではありません。したがって、それは(例えば何かが組み込みであるかどうかを伝えることはできませんwhich echotype echo)。
チョロバ

私はそれがあなたが使用しているシェルに依存すると思います:type which which is a shell builtin私はzshを使用しています。
数学

@math:元の質問には/ bashというタグが付けられています。
チョロバ

7

最初の質問として、競合をリストする方法はありません。bashはハッシュテーブルを内部で使用するため、最後のオーバーライドのみを記録します。

コマンドがエイリアスであるかどうかを調べるには、alias ls「not found」などのように表示される場合はエイリアスではなく、そうでない場合は、ケースで使用します。

エイリアスを無視して元の関数を起動するには、スラッシュを前に付けます。たとえば\ls、実際のハッシュされたlsを起動し、エイリアスを無視します。

編集

コマンドがエイリアスかどうかをすばやく知りたい場合は、次のコマンドset -xを実行すると、デバッグモードを有効にできますls

ここに画像の説明を入力してください

実行されている実際のコマンドのデバッグ出力が表示されます

デバッグモードを設定解除するには、次を使用します set -


ありがとう。しかし、役に立たなかったalias。ユーザーがコマンドの存在を知らない場合(例ls)彼が実行後に知っているように見えるのalias lsは、それが最初にマップされたものではなく、何にマップされるかだけです。競合を見つけるには、\の有無にかかわらずすべてのコマンドを実行する必要があると思います。
user13107

@ user13107が回答を更新しました
デイジー

ありがとう。トレースを設定解除するにはどうすればよいですか?
user13107

@ user13107が再び更新されました;-P
デイジー

1
「競合をリストする方法はありません」-あなたは想像力に欠けています。
-camh

6

bashビルトインcompgenを使用して、を使用してすべてのコマンドとすべてのエイリアスのリストを取得できますcompgen -ac。エイリアスでもあるコマンドはすべてこのリストで複製されるため、単純な単純な解決策は、の出力で重複を探すことですcompgen -ac

ただし、コマンドがパス上に2回ある場合にも重複が表示される場合があります。例えば、私は持っ/bin/whichている/usr/bin/whichので、エイリアスではないのに2回compgen -acリストwhichします。

したがって、必要なのは、すべての重複を取得し、compgen -acそれをエイリアスのリストと比較することです。エイリアスでもある重複のみが、コマンドを隠すエイリアスです。comm(1)コマンドとbashプロセス置換を使用してこれを行うことができます。

comm -12 <(compgen -a | sort) <(compgen -ac | sort | uniq -d) 

compgen -a | sortすべてのエイリアスのリストです(でソートcomm)。compgen -ac | sort | uniq -dコマンドとエイリアスのリストからのすべての重複のリストです。comm -12両方に共通の行のみを出力します。


5

シェルデバッグ機能を使用して、bashが対話型シェルを呼び出したときに何が起こっているかを正確に確認できます。以下は、対話型シェルがログインシェルから生成されたときに割り当てられるすべてのエイリアスを示しています。

bash -x -l -i -c 'exit' 2>&1 | grep ' alias '
  • -x ->デバッグを有効にする
  • -l ->ログインシェル
  • -i ->インタラクティブシェル
  • -c ->コマンド

シェルが戻るためには、コマンド出口を実行する必要があります。これ-iは、bashがコマンドを実行するための対話型環境をセットアップしないためです。

これが私のシステムの例です:

$ bash -x -l -i -c 'exit' 2>&1 | grep ' alias '
++ alias 'ls=ls --color=auto'
$ alias -p
alias ls='ls --color=auto'

エイリアスが割り当てられたときに最後にソースされたファイルを確認して、発生したファイルを特定するには、grepを拡張できます。

bash -x -l -i -c 'exit' 2>&1 | grep -E ' (alias|[.]|source) '

これは誤検知を返す場合がありますが、返されたデータを手動で検査している場合は問題ありません。実行されたコマンドの前の「+」記号の数は深さを示します。

+ . /home/jordan/.bashrc
++ alias 'ls=ls --color=auto'
++ . /home/jordan/.foo
+++ alias t=test
++ alias t=test2

この出力例では、.bashrcがls.foo aliasesのエイリアスを設定し、t.bashrcが以前のエイリアスを上書きすることを示していますt


ありがとう。これは確かに便利ですが、エイリアスを作成する競合をどのように見つけるかを見ることができません。
user13107

@ user13107役立つはずの詳細をいくつか追加しました。エイリアスを新しい値に設定することは、「競合する」エイリアスではありません。通常の文書化された動作であるため、ラウンドアバウト方法が必要です。
ヨルダン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.