เป็นไปได้หรือไม่ที่จะใช้คำสั่ง builtin กับ Bash?


13

ได้รับแรงบันดาลใจจากคำถามนี้ชื่อ: เมื่อใดที่คำสั่งในตัวถูกโหลดไปยังหน่วยความจำในขณะที่พยายามตอบคำถามนี้ฉันลองใช้คำสั่งต่อไปนี้และรู้สึกประหลาดใจเล็กน้อยที่ฉันไม่สามารถเรียกใช้:

$ strace cd $HOME

มีวิธีที่ฉันสามารถใช้เพื่อรัน strace สำหรับคำสั่ง builtin เพื่อ Bash หรือไม่?


1
ทำไมคุณถึงคิดว่ามันน่าแปลกใจที่การstraceไม่รันโปรแกรมไม่ส่งผลให้เกิดร่องรอย
Bananguin

คำตอบ:


15

หากคุณคิดเกี่ยวกับวิธีการstraceทำงานมันก็สมเหตุสมผลแล้วว่าไม่มีสิ่งใดในตัวของ Bash ที่สามารถตรวจสอบย้อนกลับได้ straceสามารถติดตามสิ่งที่เกิดขึ้นจริงในขณะที่ builtins ไม่

ตัวอย่างเช่นcdคำสั่งของฉัน:

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

เคล็ดลับสำหรับ strace'ing cd?

ฉันได้พบกับเทคนิคนี้ที่คุณสามารถเรียกใช้straceในbashกระบวนการจริงและการทำเช่นนั้นติดตามcdทางนั้น

ตัวอย่าง

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

ซึ่งผลลัพธ์ในฉันสามารถ strace bashกระบวนการดังนี้:

....
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, 

นี่คือพรอมต์ Bash ที่ซึ่งรออยู่เพื่อรออินพุต ดังนั้นให้มันออกคำสั่ง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, 

จากเอาต์พุตด้านบนคุณสามารถดูตำแหน่งที่ฉันพิมพ์คำสั่งcd ..และกด Enter, ( \n) จากตรงนั้นคุณจะเห็นว่าstat()ฟังก์ชั่นนั้นถูกเรียกใช้และหลังจากนั้น Bash กำลังนั่งที่read(0..พรอมต์อื่นรอคำสั่งอื่น



โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.