Có thể sải bước các lệnh dựng sẵn cho Bash?


12

Lấy cảm hứng từ câu hỏi này, có tiêu đề: Khi nào các lệnh tích hợp được tải vào bộ nhớ , trong khi cố gắng trả lời điều này, tôi đã thử lệnh sau và hơi ngạc nhiên khi tôi không thể chạy nó:

$ strace cd $HOME

Có phương pháp nào tôi có thể sử dụng để chạy strace cho các lệnh dựng sẵn cho Bash không?


1
Tại sao bạn nghĩ rằng thật đáng ngạc nhiên khi việc stracekhông chạy chương trình không dẫn đến dấu vết?
Bananguin

Câu trả lời:


14

Nếu bạn nghĩ về cách thức stracehoạt động thì điều đó hoàn toàn có ý nghĩa rằng không có nội dung nào trong Bash sẽ có thể truy nguyên được. stracechỉ có thể theo dõi các thực thi thực tế, trong khi các nội dung thì không.

Ví dụ cd: lệnh của tôi :

$ type cd
cd is a function
cd () 
{ 
    builtin cd "$@";
    local result=$?;
    __rvm_project_rvmrc;
    __rvm_after_cd;
    return $result
}

Thủ thuật cho cd strace'ing?

Tôi đã xem qua kỹ thuật này, nơi bạn có thể gọi ra quy trình stracethực tế bashvà bằng cách đó, gián tiếp theo dõi theo cdcách đó.

Thí dụ

$ stty -echo
$ cat | strace bash > /dev/null

Kết quả là tôi có thể bashtiến hành quá trình như sau:

....
getegid()                               = 501
getuid()                                = 500
getgid()                                = 501
access("/bin/bash", X_OK)               = 0
stat("/bin/bash", {st_mode=S_IFREG|0755, st_size=940312, ...}) = 0
geteuid()                               = 500
getegid()                               = 501
getuid()                                = 500
getgid()                                = 501
access("/bin/bash", R_OK)               = 0
getpgrp()                               = 32438
rt_sigaction(SIGCHLD, {0x43e360, [], SA_RESTORER, 0x34e7233140}, {SIG_DFL, [], SA_RESTORER, 0x34e7233140}, 8) = 0
getrlimit(RLIMIT_NPROC, {rlim_cur=1024, rlim_max=62265}) = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
fcntl(0, F_GETFL)                       = 0 (flags O_RDONLY)
fstat(0, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
lseek(0, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
read(0, 

Đây là dấu nhắc Bash, nơi nó đang ngồi đó, chờ đợi một số đầu vào. Vì vậy, hãy cho nó lệnh cd ..:

read(0, "c", 1)                         = 1
read(0, "d", 1)                         = 1
read(0, " ", 1)                         = 1
read(0, ".", 1)                         = 1
read(0, ".", 1)                         = 1
read(0, "\n", 1)                        = 1
stat("/home", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat("/home/saml", {st_mode=S_IFDIR|0700, st_size=32768, ...}) = 0
stat("/home/saml/tst", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0
stat("/home/saml/tst/90609", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0
stat("/home/saml/tst/90609", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0
chdir("/home/saml/tst")                 = 0
rt_sigprocmask(SIG_BLOCK, NULL, [], 8)  = 0
read(0, 

Từ đầu ra trên, bạn có thể thấy nơi tôi đã gõ lệnh cd ..và nhấn enter, ( \n). Từ đó bạn có thể thấy rằng stat()hàm đã được gọi và sau đó Bash đang ngồi ở một read(0..dấu nhắc khác , chờ lệnh khác.


7

Để stracevỏ làm cd /some/dir:

{ strace -p "$$" & sleep 1; cd /some/dir; kill "$!"; }

Tại sao $1ở đây, vì bash, điều này không nên %hay %1?
Graeme

1

Bạn có thể thử như sau:

strace bash -c <command/builtin>

Ví dụ:

strace bash -c 'cd /path/to/destination/'
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.