Чи можна розтягнути вбудовані команди до Bash?


13

Натхненний цим питанням під назвою: Коли вбудовані команди завантажуються в пам'ять , намагаючись відповісти на це, я спробував наступну команду і трохи здивувався, що не зміг її виконати:

$ strace cd $HOME

Чи є метод, яким я можу скористатися, щоб запустити strace для вбудованих команд до Bash?


1
Чому, на вашу думку, дивно, що straceвід не запуску програми не залишається сліду?
Bananguin

Відповіді:


15

Якщо ви задумаєтесь про те, як це straceпрацює, то має сенс, що жодна з побудованих до Баша не простежується. straceможна простежити лише реальні файли, тоді як вбудовані - ні.

Наприклад, моя 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

Це призводить до того, що я можу зробити 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..підказкою, чекаючи чергової команди.



1

Ви можете спробувати наступне:

strace bash -c <command/builtin>

Наприклад:

strace bash -c 'cd /path/to/destination/'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.