GNU/Linux >> Linux Esercitazione >  >> Linux

È possibile tracciare i comandi integrati su Bash?

Ispirato da questa domanda, intitolata:Quando vengono caricati in memoria i comandi integrati, mentre tentavo di rispondere ho provato il comando seguente e sono rimasto un po' sorpreso di non poterlo eseguire:

$ strace cd $HOME

C'è un metodo che posso utilizzare per eseguire strace per i comandi integrati in Bash?

Risposta accettata:

Se pensi a come strace funziona, quindi ha assolutamente senso che nessuno dei builtin di Bash sia rintracciabile. strace può tracciare solo eseguibili effettivi, mentre i builtin non lo sono.

Ad esempio, il mio cd comando:

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

Trucco per strace'ing cd?

Mi sono imbattuto in questa tecnica in cui potresti invocare strace sull'attuale bash processare e, così facendo, tracciare indirettamente cd in questo modo.

Esempio

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

Il che si traduce in me in grado di tracciare il bash procedere come segue:

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

Questo è il prompt di Bash, dove è seduto lì, in attesa di input. Quindi diamogli il 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, 

Dall'output sopra, puoi vedere dove ho digitato il comando, cd .. e premi invio, (n ). Da lì puoi vedere che il stat() è stata chiamata la funzione e che in seguito Bash è seduto su un altro read(0.. prompt, in attesa di un altro comando.


Linux
  1. Comandi Bash bang:un trucco da conoscere per la riga di comando di Linux

  2. Personalizzazione della shell Bash

  3. Il comando "eval" in Bash?

  4. È possibile emulare versioni precedenti di Bash?

  5. Necessità del builtin "costruito"?

Cos'è Git Bash; Lavorare con i comandi Git Bash

Come utilizzare il comando di lettura Bash

Salva la giornata con successo con i comandi della cronologia di Bash

Come modificare il numero di comandi archiviati in Bash History

Come posso utilizzare i comandi watch e jobs insieme in Bash?

È possibile recuperare il contenuto di uno script bash in esecuzione dalla RAM