Inspirado por esta pregunta, titulada:¿Cuándo se cargan los comandos incorporados en la memoria? Mientras intentaba responder a esto, probé el siguiente comando y me sorprendió un poco no poder ejecutarlo:
$ strace cd $HOME
¿Hay algún método que pueda utilizar para ejecutar strace para los comandos integrados de Bash?
Respuesta aceptada:
Si piensas en cómo strace
funciona, entonces tiene mucho sentido que ninguno de los componentes integrados de Bash sea rastreable. strace
solo puede rastrear ejecutables reales, mientras que los integrados no lo son.
Por ejemplo, mi cd
comando:
$ type cd
cd is a function
cd ()
{
builtin cd "[email protected]";
local result=$?;
__rvm_project_rvmrc;
__rvm_after_cd;
return $result
}
¿Truco para rastrear un CD?
Encontré esta técnica en la que podías invocar strace
en el bash
actual proceso y, al hacerlo, rastrear indirectamente cd
de esa manera.
Ejemplo
$ stty -echo
$ cat | strace bash > /dev/null
Lo que me permite rastrear el bash
proceso de la siguiente manera:
....
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,
Este es el indicador de Bash, donde está sentado esperando alguna entrada. Así que vamos a darle el comando 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,
De la salida anterior, puede ver dónde escribí el comando, cd ..
y presiona enter, (n
). Desde allí puedes ver que el stat()
se llamó a la función, y que luego Bash está sentado en otro read(0..
aviso, esperando otro comando.