Làm cách nào để kiểm tra các xung đột có thể xảy ra trong khi sử dụng bí danh trong bashrc?


12

Có một cách đơn giản để liệt kê tất cả các xung đột lệnh đã xảy ra trong hệ thống do cập nhật bashrc liên quan đến các lệnh bí danh?

Ví dụ, ai đó viết alias ls=/path/to/user-generated/executablebằng bashrc. Làm thế nào để người ta phát hiện ra rằng điều này đang che giấu một lệnh thực tế ( ls). Một cách dường như là chạy tất cả các bí danh trước và sau khi tìm nguồn bashrc và tìm khác biệt đầu ra. Có cách nào tốt hơn không?

Tôi đang chạy Ubuntu 12.04.

bash

GNU bash, phiên bản 4.2.24 (1) -release (i686-pc-linux-gnu)


Là một lưu ý phụ, thông thường sẽ hữu ích hơn cho mọi người khi trả lời nếu bạn cung cấp phiên bản bash của bạn, thay vì phiên bản HĐH khi đặt câu hỏi cụ thể cho bash.
jordanm

@jordanm Cập nhật.
dùng13107

Câu trả lời:


8

Để tìm ra những lệnh nào được che dấu bởi các bí danh, hãy làm một cái gì đó như thế này:

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

Giải trình

aliasmột mình liệt kê các bí danh được xác định và sedtrích xuất tên của họ. Vòng lặp while chạy type -tatrên mỗi chúng và awkin các dòng chứa cả bí danh và tệp.


15

Bạn có thể sử dụng typeđể tìm hiểu làm thế nào một lệnh sẽ được giải thích bằng bash.


Ví dụ, type lsin ls is aliased to `ls --color=auto'ở đây.
l0b0

Tương tự cũng hoạt động với which, nhưng bây giờ tôi không biết nếu cả hai (loại, mà) dựng sẵn vỏ giống nhau.
toán

@math: type whichcho bạn biết which is /usr/bin/which, vì vậy nó không phải là nội dung. Do đó, nó không thể cho bạn biết liệu thứ gì đó có phải là nội dung hay không (ví dụ which echoso với type echo).
choroba

Tôi đoán nó phụ thuộc vào shell bạn sử dụng: type which which is a shell builtinTôi đang sử dụng zsh.
toán

@math: Câu hỏi ban đầu được gắn thẻ / bash.
choroba

7

Như câu hỏi đầu tiên của bạn, không có cách nào để liệt kê các xung đột, vì bash sử dụng bảng băm bên trong, nó chỉ ghi lại ghi đè cuối cùng.

Để tìm hiểu xem một lệnh có phải là bí danh hay không, hãy sử dụng alias lstrong trường hợp của bạn, nếu nó cho bạn biết một cái gì đó như "không tìm thấy" thì đó không phải là bí danh, nếu không thì đó là.

Để khởi chạy chức năng ban đầu bỏ qua bí danh, tiền tố một dấu gạch chéo, ví dụ: \lssẽ khởi chạy ls băm thực, bỏ qua bí danh.

BIÊN TẬP

Nếu bạn muốn biết nhanh nếu một lệnh là bí danh, bạn có thể bật chế độ gỡ lỗi bằng cách set -x, ngay bây giờ nếu bạn thực thi ls:

nhập mô tả hình ảnh ở đây

Bạn sẽ thấy một đầu ra gỡ lỗi của lệnh thực sự đang được thực thi

Để bỏ đặt chế độ gỡ lỗi, sử dụng set -


Cảm ơn. Nhưng đã không nhận được aliasmột phần. Điều gì xảy ra nếu người dùng không biết rằng có tồn tại một lệnh (ví dụ ls)? Điều duy nhất anh ta dường như biết sau khi chạy alias lslà những gì nó được ánh xạ và không phải là những gì nó được ánh xạ ban đầu. Tôi đoán người ta sẽ phải chạy tất cả các lệnh có và không có \ để tìm xung đột.
dùng13107

@ user13107 đã cập nhật câu trả lời
daisy

Cảm ơn. Làm thế nào để tôi bỏ dấu vết?
dùng13107

@ user13107 được cập nhật lại ;-P
daisy

1
"Không có cách nào để liệt kê các xung đột" - bạn không đủ sức tưởng tượng.
camh

6

Bạn có thể sử dụng bash dựng sẵn compgenđể lấy danh sách tất cả các lệnh và tất cả các bí danh sử dụng compgen -ac. Bất kỳ lệnh nào cũng là bí danh sẽ được sao chép trong danh sách này, vì vậy giải pháp ngây thơ đơn giản là tìm kiếm các bản sao trong đầu ra của compgen -ac.

Tuy nhiên, các bản sao cũng có thể xuất hiện nếu một lệnh nằm trên đường dẫn hai lần. Chẳng hạn, tôi có /bin/which/usr/bin/whichvì vậy compgen -acsẽ liệt kê whichhai lần mặc dù nó không phải là bí danh.

Vì vậy, những gì cần thiết là để có được tất cả các bản sao từ compgen -acvà so sánh nó với một danh sách các bí danh. Chỉ các bản sao cũng là bí danh là những bí danh ẩn các lệnh. Chúng ta có thể làm điều này với comm(1)lệnh và với sự thay thế quá trình bash.

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

compgen -a | sortlà danh sách tất cả các bí danh (được sắp xếp cho comm). compgen -ac | sort | uniq -dlà danh sách tất cả các bản sao từ danh sách các lệnh và bí danh. comm -12chỉ xuất ra những dòng chung cho cả hai.


5

Bạn có thể sử dụng tính năng gỡ lỗi shell để xem chính xác những gì đang xảy ra khi bash gọi shell tương tác. Sau đây sẽ cho bạn thấy tất cả các bí danh được gán khi một vỏ tương tác được sinh ra từ một vỏ đăng nhập:

bash -x -l -i -c 'exit' 2>&1 | grep ' alias '
  • -x -> cho phép gỡ lỗi
  • -l -> vỏ đăng nhập
  • -i -> vỏ tương tác
  • -c -> lệnh

Chạy lệnh thoát được yêu cầu để shell trả về. Điều -inày là bắt buộc trong trường hợp này vì bash sẽ không thiết lập môi trường tương tác để chạy lệnh khác.

Đây là một ví dụ từ hệ thống của tôi:

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

Để xem tệp nào được lấy nguồn cuối cùng khi bí danh được chỉ định để xác định tệp đã xảy ra, bạn có thể mở rộng grep:

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

Điều này có thể trả về dương tính giả, nhưng sẽ ổn nếu bạn đang kiểm tra thủ công dữ liệu được trả về. Số lượng các ký hiệu '+' phía trước lệnh được thực thi cho biết độ sâu.

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

Trong đầu ra mẫu này, nó cho thấy .bashrc đặt bí danh cho ls, bí danh .foo tvà sau đó .bashrc ghi đè lên bí danh trước đó của t.


Cảm ơn. Điều này chắc chắn hữu ích, nhưng không thể thấy làm thế nào nó tìm thấy xung đột tạo bí danh.
dùng13107

@ user13107 Tôi đã thêm một số chi tiết sẽ hữu ích. Đặt bí danh thành giá trị mới không phải là bí danh "xung đột". Đó là hành vi được ghi chép bình thường, đó là lý do tại sao cần có một cách làm tròn.
jordanm
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.