perché strace ignora il mio alias per rm?


8

Ho un aliasset per il mio rmcomando. Se eseguo il aliascomando, questo è ciò che ottengo come output.

alias rm='rm -i'

Ora, quando eseguo il rmcomando funziona perfettamente come previsto.

rm ramesh
rm: remove regular empty file `ramesh'? y

Ora, stavo imparando le chiamate di sistema che vengono chiamate quando eseguo un comando. Per questo ho avuto modo di conoscere il stracecomando da qui che mi elenca i file che vengono chiamati quando eseguo un comando. Il comando è come di seguito.

strace -ff -e trace=file rm ramesh 2>&1 

Il comando funziona perfettamente, tranne per il fatto che ignora i miei alias che ho in atto per il mio rmcomando. Elimina il file senza richiedere all'utente.

Quindi, straceignora gli alias in questo modo? Se è così, perché è così?

MODIFICARE:

Non sono sicuro, se questo ha qualcosa da fare ma type -a rmmi dà l'output come,

rm is aliased to `rm -i'
rm is /bin/rm

Quindi sta considerando /bin/rmin questo caso quale è il motivo per cui all'utente non viene richiesto prima della cancellazione?


3
stracenon ignora gli alias, perché ciò implicherebbe che c'era qualcosa da ignorare in primo luogo. Un alias è una caratteristica della shell. straceè un programma diverso e all'interno stracedel concetto di alias non esiste, quindi non c'è nulla da ignorare. L'API fornita dal kernel per l'esecuzione dei programmi non ha neanche un concetto di alias, quindi non c'è modo in cui la shell possa dire la storia degli alias, anche se lo volesse.
Kasperd,

1
Se vuoi straceun alias, devi utilizzare stracela shell, che implementa l'alias. Ci sono alcuni approcci che potresti adottare per farlo: strace -p $$ &o strace bashoppure strace sh -c 'rm ramesh'(l'ultimo ignorerà anche l'alias, ma per una ragione completamente diversa.)
kasperd

Risposte:


20

stracenon funziona rm -iper lo stesso motivo di:

echo rm

non emette rm -i.

Gli alias sono una caratteristica di alcune shell per consentire che alcune stringhe vengano automaticamente sostituite da altre quando si trovano nella posizione di comando.

In:

alias foo='whatever'
foo xxx

Le shell si espandono per:

whatever xxx

e questo subisce un altro giro di interpretazione, in quel caso che porta all'esecuzione del whatevercomando.

gli alias vengono espansi solo quando si trovano nella posizione di comando (come prima parola di una riga di comando).

zshsupporta globale alias .

Potresti fare:

alias -g rm='rm -i'

Ma non vorrai, poiché ciò significherebbe che:

echo rm

uscirà rm -iper esempio.


8

straceusa la PATHvariabile d'ambiente per localizzare il programma da tracciare, piuttosto che eseguirlo attraverso la shell (che ingombrerebbe l'output). Un alias di shell non è un programma, è una funzionalità della shell e cosìstrace ignora.

Correre strace strace rmè piuttosto illuminante, oltre ad essere interessante ricorsivo.


5

Un alias è una caratteristica della tua shell. Tuttavia, strace esegue direttamente il comando (usandoexecve , probabilmente), che non coinvolge la shell. (Se strace eseguisse il comando dato attraverso la shell, l'output di strace conterrebbe tutte le scale di programma dell'esecuzione della shell anziché solo quelle del processo di interesse.)

Inoltre, quando esegui strace rm ramesh, la shell interattiva non tenta di sostituire il tuo alias negli argomenti da stracciare, perché ciò sarebbe terribilmente confuso per tutti. La shell espande solo gli alias che appaiono nella prima posizione su una riga di comando.


2

strace usa execve c functioncome find command, tuttavia find uses exec functionnon puoi usare aliases,built-in shell command o così via.

Devi fare:

strace /bin/rm -i ramesh

2

Basarsi sulla risposta di Stéphane Chazelas, se definito

alias strace="strace "

(con uno spazio alla fine) quindi il comando

strace rm ramesh

verrà elaborato come

strace rm -i ramesh

Ma anche questo funzionerà solo per la prima parola dopo il strace, quindi non si applica direttamente al tuo esempio (dove hai opzioni intermedie).  Ma, se lo definisci

alias my_strace="strace -ff -e trace=file "

poi

my_strace rm ramesh

verrà elaborato come

strace -ff -e trace=file rm -i ramesh

2

Nessun alias qui

Supponiamo di avere la definizione di alias alias rm='rm -i'nel nostro ~/.bashrc. L'alias aggiunge l'opzione per la richiesta prima di rimuovere ogni file:

$ touch ./file
$ rm ./file
/bin/rm: remove regular empty file ‘./file’? 

Non è colpa di straceciò che non ha usato l'alias: non
ha proprio nulla a che fare con gli alias.

Nel comando

$ strace -f -e file -o rm.strace rm ./file

Le parole rme ./filesono solo argomenti per strace per ora - la shell non può espandere l'alias rm, perché non può sapere che strace utilizzerà questi argomenti come comando in seguito.

In generale, gli alias di comando possono essere utilizzati solo dove possono essere i comandi.

Gli alias sono una caratteristica della shell e stracenon usano affatto una shell quando chiama il comando dalla riga di comando. Utilizza exec()invece, con i comandi e gli argomenti dalla propria riga di comando.

All'interno di strace, il comando verrà chiamato con qualcosa di simile a exec("rm", "file")e exec()troverà/bin/rm in PERCORSO - senza usare una shell.

Shell esplicita

Ora, perché non includere una shell nel stracecomando?

$ touch ./file
$ strace -f -e file -o rm.strace bash -c 'rm ./file'
$ ls ./file
ls: cannot access ./file: No such file or directory

Hmm ... che non ha funzionato. rmappena eliminato il file, senza il -iprompt.

Alias ​​interattivi

Gli alias sono normalmente abilitati solo nelle shell interattive, linee di comando effettive in un terminale.
Con il nostro alias di esempio, è facile capire perché ciò abbia un senso: se l' rm -ialias si espandesse all'interno degli script della shell, si bloccherebbero inizialmente rmcon nessuno lì a premere y.

Gli alias sono controllati dall'opzione shell expand_aliases. Potremmo impostare l'opzione con bash +O expand_aliases -c .... Ma questo non è abbastanza, perché anche la shell non interattiva non leggerà ~/.bashrc. Ciò significa che il nostro alias non è solo disattivato dall'opzione, ma non è nemmeno definito.

Fingendo di essere interattivo

Il modo più semplice per gestire entrambe le parti è utilizzare l'opzione della riga di comando -iper far sì che la shell finga di essere interattiva:

$ touch ./file
$ strace -f -e file -o rm.strace bash -i -c 'rm ./file'
/bin/rm: remove regular empty file ‘./file’?

Finalmente è -istato usato l' alias!

Si noti che normalmente non si utilizzano shell in esecuzione con l' -iopzione per gli script, anche se si desidera avere i propri alias disponibili, ad esempio.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.