Bagaimana cara menguji kemungkinan konflik saat menggunakan alias di bashrc?

12

Apakah ada cara sederhana untuk mendaftar semua konflik perintah yang terjadi di sistem karena pembaruan bashrc yang melibatkan perintah alias?

Misalnya, seseorang menulis alias ls=/path/to/user-generated/executabledi bashrc. Bagaimana orang mengetahui bahwa ini menutupi perintah sebenarnya ( ls). Salah satu cara tampaknya menjalankan semua alias sebelum dan sesudah sumber bashrc dan diff output. Apakah ada cara yang lebih baik?

Saya menjalankan Ubuntu 12.04.

bash --versi

GNU bash, versi 4.2.24 (1) -release (i686-pc-linux-gnu)

pengguna13107
sumber
Sebagai catatan, biasanya lebih bermanfaat bagi orang-orang yang menjawab jika Anda memberikan versi bash Anda, daripada versi OS ketika mengajukan pertanyaan yang spesifik untuk bash.
jordanm
@jordanm Diperbarui.
user13107

Jawaban:

8

Untuk mengetahui perintah apa yang ditutupi oleh alias, lakukan sesuatu seperti ini:

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

Penjelasan

aliassendiri daftar alias yang telah ditentukan dan sedekstrak namanya. Loop sementara berjalan type -tadi masing-masing dan awkmencetak garis yang berisi alias dan file.

Thor
sumber
15

Anda dapat menggunakan typeuntuk mencari tahu bagaimana suatu perintah akan ditafsirkan oleh bash.

choroba
sumber
Misalnya, type lscetak di ls is aliased to `ls --color=auto'sini.
l0b0
Sama tidak bekerja dengan which, tapi saya tidak sekarang jika keduanya (tipe, yang) shell builtin sama.
matematika
@math: type whichmemberitahu Anda which is /usr/bin/which, jadi itu bukan builtin. Oleh karena itu, tidak dapat memberi tahu Anda apakah sesuatu itu builtin atau tidak (misalnya which echoversus type echo).
choroba
Saya kira itu tergantung pada shell yang Anda gunakan: type which which is a shell builtinSaya menggunakan zsh.
matematika
@math: Pertanyaan aslinya diberi tag / bash.
choroba
7

Sebagai pertanyaan pertama Anda, tidak ada cara untuk membuat daftar konflik, karena bash menggunakan tabel hash secara internal, itu hanya mencatat override terakhir.

Untuk mengetahui apakah suatu perintah adalah alias, gunakan alias lsdalam kasus Anda, jika itu memberi tahu Anda sesuatu seperti "tidak ditemukan" maka itu bukan alias, jika tidak demikian.

Untuk menjalankan fungsi asli dengan mengabaikan alias, awali slash, mis. \lsAkan meluncurkan hass asli, abaikan alias.

EDIT

Jika Anda ingin mengetahui dengan cepat jika suatu perintah adalah alias, Anda dapat mengaktifkan mode debugging dengan set -x, sekarang jika Anda menjalankan ls:

masukkan deskripsi gambar di sini

Anda akan melihat output debug dari perintah yang sebenarnya dieksekusi

Untuk membatalkan mode debug, gunakan set -

bunga aster
sumber
Terima kasih. Tetapi tidak mendapatkan aliasbagian. Bagaimana jika pengguna tidak tahu bahwa ada perintah (misalnya ls)? Satu-satunya hal yang tampaknya dia ketahui setelah berlari alias lsadalah apa yang dipetakan dan bukan apa yang awalnya dipetakan. Saya kira kita harus menjalankan semua perintah dengan dan tanpa \ untuk menemukan konflik.
user13107
@ user13107 memperbarui jawabannya
daisy
Terima kasih. Bagaimana cara menghapus pelacakan?
user13107
@ user13107 diperbarui lagi ;-P
daisy
1
"tidak ada cara untuk membuat daftar konflik" - Anda tidak cukup imajinatif.
camh
6

Anda dapat menggunakan bash builtin compgenuntuk mendapatkan daftar semua perintah dan semua alias yang digunakan compgen -ac. Perintah apa pun yang juga merupakan alias akan diduplikasi dalam daftar ini, sehingga solusi naif sederhana adalah mencari duplikat di output compgen -ac.

Namun, duplikat juga dapat muncul jika perintah ada di jalur dua kali. Misalnya, saya punya /bin/whichdan /usr/bin/whichbegitu compgen -acakan daftar whichdua kali meskipun tidak alias.

Jadi yang diperlukan adalah mengambil semua duplikat compgen -acdan membandingkannya dengan daftar alias. Hanya duplikat yang juga alias yang merupakan alias yang menyembunyikan perintah. Kita bisa melakukan ini dengan comm(1)perintah dan dengan substitusi proses bash.

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

compgen -a | sortadalah daftar semua alias (diurutkan untuk comm). compgen -ac | sort | uniq -dadalah daftar semua duplikat dari daftar perintah dan alias. comm -12hanya menghasilkan garis-garis yang umum untuk keduanya.

camh
sumber
5

Anda dapat menggunakan fitur debugging shell untuk melihat apa yang terjadi ketika bash memanggil shell interaktif. Yang berikut ini akan menunjukkan kepada Anda semua alias yang ditugaskan ketika shell interaktif dihasilkan dari shell login:

bash -x -l -i -c 'exit' 2>&1 | grep ' alias '
  • -x -> aktifkan debugging
  • -l -> shell login
  • -i -> shell interaktif
  • -c -> perintah

Menjalankan perintah keluar diperlukan agar shell kembali. The -idiperlukan dalam kasus ini karena bash tidak akan mendirikan sebuah lingkungan yang interaktif untuk menjalankan perintah sebaliknya.

Ini adalah contoh dari sistem saya:

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

Untuk melihat file apa yang terakhir kali diambil ketika alias ditugaskan untuk menentukan file itu terjadi, Anda dapat memperluas grep:

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

Ini mungkin mengembalikan positif palsu, tetapi harus baik-baik saja jika Anda memeriksa secara manual data yang dikembalikan. Jumlah simbol '+' di depan perintah yang dieksekusi menunjukkan kedalaman.

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

Dalam output sampel ini, ini menunjukkan bahwa .bashrc menetapkan alias untuk ls, .foo alias t, dan kemudian .bashrc menimpa alias sebelumnya dari t.

jordanm
sumber
Terima kasih. Ini tentu saja bermanfaat, tetapi tidak dapat melihat bagaimana konflik itu menemukan alias.
user13107
@ user13107 Saya menambahkan beberapa detail lagi yang seharusnya membantu. Mengatur alias ke nilai baru bukanlah alias "bentrok". Ini adalah perilaku normal yang terdokumentasi, oleh karena itu diperlukan cara yang bulat.
jordanm