Tại sao strace bỏ qua bí danh của tôi cho rm?


8

Tôi có một aliasbộ cho rmlệnh của tôi . Nếu tôi chạy aliaslệnh, đây là những gì tôi nhận được như đầu ra.

alias rm='rm -i'

Bây giờ, khi tôi chạy rmlệnh, nó hoạt động tốt như mong đợi.

rm ramesh
rm: remove regular empty file `ramesh'? y

Bây giờ, tôi đã học được trên các cuộc gọi hệ thống đang được gọi khi tôi thực hiện một lệnh. Vì vậy, tôi đã biết về stracelệnh từ đây liệt kê cho tôi các tệp đang được gọi khi tôi thực thi một số lệnh. Lệnh như dưới đây.

strace -ff -e trace=file rm ramesh 2>&1 

Lệnh hoạt động hoàn toàn tốt, ngoại trừ việc nó bỏ qua các bí danh mà tôi có tại chỗ cho rmlệnh của mình . Nó xóa tập tin mà không nhắc người dùng.

Vì vậy, có stracebỏ qua bí danh như thế này? Nếu vậy tại sao nó lại như vậy?

BIÊN TẬP:

Không chắc chắn, nếu điều này có gì đó để làm nhưng type -a rmcung cấp cho tôi đầu ra như,

rm is aliased to `rm -i'
rm is /bin/rm

Vì vậy, nó đang xem xét /bin/rmtrong trường hợp này đó là lý do tại sao người dùng không được nhắc trước khi xóa?


3
stracekhông bỏ qua bí danh, bởi vì điều đó sẽ ngụ ý có một cái gì đó để bỏ qua ở nơi đầu tiên. Một bí danh là một tính năng của vỏ. stracelà một chương trình khác nhau, và bên trong stracekhái niệm bí danh không tồn tại, do đó không có gì để bỏ qua. API được cung cấp bởi kernel để thực thi các chương trình cũng không có khái niệm bí danh, vì vậy không có cách nào shell có thể nói về bước đi về bí danh, ngay cả khi nó muốn.
kasperd

1
Nếu bạn muốn stracemột bí danh, bạn phải vào stracetrình bao, thực hiện bí danh. Có một vài phương pháp bạn có thể làm để làm điều đó: strace -p $$ &hoặc strace bashhoặc strace sh -c 'rm ramesh'(ý chí cuối cùng cũng bỏ qua các bí danh, nhưng đối với một lý do hoàn toàn khác nhau.)
kasperd

Câu trả lời:


20

stracekhông chạy rm -ivì lý do tương tự như:

echo rm

không đầu ra rm -i.

Bí danh là một tính năng của một vài shell để cho phép một số chuỗi tự động được thay thế bởi một chuỗi khác khi được tìm thấy ở vị trí lệnh.

Trong:

alias foo='whatever'
foo xxx

Các vỏ mở rộng ra để:

whatever xxx

và điều đó trải qua một vòng giải thích khác, trong trường hợp đó dẫn đến thực thi whateverlệnh.

bí danh chỉ được mở rộng khi được tìm thấy ở vị trí lệnh (là từ đầu tiên của dòng lệnh).

zshhỗ trợ bí danh toàn cầu .

Bạn có thể làm:

alias -g rm='rm -i'

Nhưng bạn sẽ không muốn, vì điều đó có nghĩa là:

echo rm

sẽ xuất ra rm -iví dụ.


8

stracesử dụng PATHbiến môi trường để xác định vị trí chương trình được theo dõi, thay vì thực hiện nó thông qua trình bao (điều này sẽ làm lộn xộn đầu ra). Một bí danh shell không phải là một chương trình, nó là một tính năng của shell và vì vậy stracebỏ qua nó.

Chạy strace strace rmlà khá khai sáng, cũng như được đệ quy thú vị.


5

Một bí danh là một tính năng của vỏ của bạn. Tuy nhiên, strace thực thi lệnh trực tiếp (sử dụng execve, có thể), không liên quan đến shell. (Nếu strace thực thi lệnh đã cho thông qua shell, thì đầu ra của strace sẽ chứa tất cả các tòa nhà thực thi shell thay vì chỉ các lệnh từ quá trình quan tâm.)

Hơn nữa, khi bạn chạy strace rm ramesh, trình vỏ tương tác không cố gắng thay thế bí danh của bạn trong các đối số để sải bước, bởi vì điều đó sẽ gây nhầm lẫn khủng khiếp cho mọi người. Shell chỉ mở rộng các bí danh xuất hiện ở vị trí đầu tiên trên một dòng lệnh.


2

sử dụng strace execve c functionnhư find command, Tuy nhiên, find uses exec functionbạn không thể sử dụng aliases, built-in shell commandv.v.

Bạn phải làm:

strace /bin/rm -i ramesh

2

Để xây dựng dựa trên câu trả lời của Stéphane Chazelas, nếu bạn xác định

alias strace="strace "

(có một khoảng trắng ở cuối) sau đó là lệnh

strace rm ramesh

sẽ được xử lý như

strace rm -i ramesh

Nhưng ngay cả điều này sẽ chỉ hoạt động cho từ đầu tiên sau strace, vì vậy nó sẽ không áp dụng trực tiếp vào ví dụ của bạn (nơi bạn có các tùy chọn can thiệp).  Nhưng, nếu bạn xác định

alias my_strace="strace -ff -e trace=file "

sau đó

my_strace rm ramesh

sẽ được xử lý như

strace -ff -e trace=file rm -i ramesh

2

Không có bí danh ở đây

Giả sử chúng ta có định nghĩa bí danh alias rm='rm -i'trong ~/.bashrc. Bí danh thêm tùy chọn nhắc nhở trước khi xóa từng tệp:

$ touch ./file
$ rm ./file
/bin/rm: remove regular empty file ‘./file’? 

Đó không phải là lỗi của straceviệc nó không sử dụng bí danh:
Nó không liên quan gì đến bí danh.

Trong lệnh

$ strace -f -e file -o rm.strace rm ./file

Các từ rm./filechỉ là đối số cho strace bây giờ - shell không thể mở rộng bí danh rm, bởi vì nó không thể biết rằng strace sẽ sử dụng các đối số này làm lệnh sau này.

Nói chung, các bí danh lệnh chỉ có thể được sử dụng khi các lệnh có thể.

Bí danh là một tính năng của shell và stracehoàn toàn không sử dụng shell khi nó gọi lệnh từ dòng lệnh. Nó sử dụng exec()thay thế, với các lệnh và đối số từ dòng lệnh của chính nó.

Bên trong strace, lệnh sẽ được gọi với một cái gì đó tương tự exec("rm", "file"), và exec()sẽ tìm thấy /bin/rmtrong PATH - mà không cần sử dụng shell.

Vỏ rõ ràng

Bây giờ, tại sao không bao gồm một shell trong stracelệnh?

$ touch ./file
$ strace -f -e file -o rm.strace bash -c 'rm ./file'
$ ls ./file
ls: cannot access ./file: No such file or directory

Hmm ... điều đó đã không làm việc. rmchỉ cần xóa các tập tin, mà không cần -inhắc.

Bí danh tương tác

Các bí danh thường chỉ được kích hoạt trong các vỏ tương tác, các dòng lệnh thực tế trong một thiết bị đầu cuối.
Với bí danh ví dụ của chúng tôi, thật dễ hiểu tại sao điều đó có ý nghĩa: Nếu rm -ibí danh sẽ được mở rộng bên trong các tập lệnh shell, chúng sẽ treo ở đầu tiên rmmà không có ai ở đó để nhấn y.

Bí danh được điều khiển bởi tùy chọn shell expand_aliases. Chúng ta có thể thiết lập tùy chọn với bash +O expand_aliases -c .... Nhưng điều đó là không đủ, bởi vì vỏ không tương tác cũng sẽ không đọc được ~/.bashrc. Điều đó có nghĩa là, bí danh của chúng tôi không chỉ bị tắt bởi tùy chọn, mà còn không được xác định.

Giả vờ tương tác

Cách dễ dàng để xử lý cả hai phần là sử dụng tùy chọn dòng lệnh -iđể tạo shell giả vờ nó tương tác:

$ touch ./file
$ strace -f -e file -o rm.strace bash -i -c 'rm ./file'
/bin/rm: remove regular empty file ‘./file’?

Cuối cùng, -ibí danh đã được sử dụng!

Lưu ý rằng thông thường bạn sẽ không sử dụng shell chạy với -itùy chọn cho kịch bản, ngay cả khi bạn muốn có bí danh của mình, ví dụ.

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.