GNU/Linux >> Tutoriales Linux >  >> Linux

¿Es posible rastrear los comandos incorporados a Bash?

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.


Linux
  1. Cómo usar los comandos del historial de Bash

  2. ¿Obtener páginas man individuales para los comandos integrados de Bash?

  3. ¿Es posible emular versiones anteriores de Bash?

  4. ¿Necesita el 'incorporado' incorporado?

  5. ¿Excluyendo algunos de los comandos para que no se almacenen en el historial de Bash?

Qué es Git Bash; Trabajar con comandos de Git Bash

Cómo usar el comando de lectura Bash

Salve el día con éxito con los comandos del historial de Bash

Cómo cambiar la cantidad de comandos almacenados en Bash History

¿Cuál es el uso de $# en Bash?

Cómo agotar el tiempo de espera de un grupo de comandos en Bash