¿Por qué strace ignora mi alias para rm?


8

Tengo un aliasconjunto para mi rmcomando. Si ejecuto el aliascomando, esto es lo que obtengo como salida.

alias rm='rm -i'

Ahora, cuando ejecuto el rmcomando funciona bien como se esperaba.

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

Ahora, estaba aprendiendo sobre las llamadas al sistema que se están llamando cuando ejecuto un comando. Para eso llegué a conocer el stracecomando desde aquí que me enumera los archivos que se llaman cuando ejecuto algún comando. El comando es el siguiente.

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

El comando funciona perfectamente bien, excepto que ignora los alias que tengo para mi rmcomando. Elimina el archivo sin preguntar al usuario.

Entonces, ¿ straceignora alias como este? Si es así, ¿por qué es así?

EDITAR:

No estoy seguro, si esto tiene algo que ver pero type -a rmme da la salida como,

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

Entonces, ¿está considerando /bin/rmen este caso por qué no se solicita al usuario antes de la eliminación?


3
straceno ignora los alias, porque eso implicaría que había algo que ignorar en primer lugar. Un alias es una característica del shell. stracees un programa diferente, y dentro stracedel concepto de alias no existe, por lo tanto no hay nada que ignorar. La API proporcionada por el núcleo para ejecutar programas tampoco tiene un concepto de alias, por lo que no hay forma de que el shell pueda decirle a Strace sobre los alias, incluso si así lo quisiera.
Kasperd

1
Si desea straceun alias, debe straceusar el shell, que implementa el alias. Hay algunos enfoques que se pueden tomar para hacer eso: strace -p $$ &o strace basho strace sh -c 'rm ramesh'(la última voluntad también ignoran el alias, pero por una razón completamente diferente.)
kasperd

Respuestas:


20

straceno funciona rm -ipor la misma razón que:

echo rm

No tiene salida rm -i.

Los alias son una característica de algunos shells para permitir que algunas cadenas sean reemplazadas automáticamente por otras cuando se encuentran en la posición de comando.

En:

alias foo='whatever'
foo xxx

Las conchas lo expanden a:

whatever xxx

y eso se somete a otra ronda de interpretación, en ese caso conduce a la ejecución del whatevercomando.

los alias solo se expanden cuando se encuentran en la posición de comando (como la primera palabra de una línea de comando).

zshadmite alias globales .

Podrías hacerlo:

alias -g rm='rm -i'

Pero no querrás, ya que eso significaría que:

echo rm

saldría rm -ipor ejemplo.


8

straceusa la PATHvariable de entorno para localizar el programa que se va a rastrear, en lugar de ejecutarlo a través del shell (lo que saturaría la salida). Un alias de shell no es un programa, es una característica del shell y, por stracelo tanto, lo ignora.

Correr strace strace rmes bastante esclarecedor, además de ser interesantemente recursivo.


5

Un alias es una característica de su shell. Sin embargo, strace ejecuta el comando directamente (usando execve, probablemente), que no involucra al shell. (Si strace ejecutó el comando dado a través del shell, entonces la salida de strace contendría todas las llamadas al sistema de ejecución del shell en lugar de solo aquellas del proceso de interés).

Además, cuando ejecuta strace rm ramesh, el shell interactivo no intenta sustituir su alias en los argumentos para enderezar, porque eso sería terriblemente confuso para todos. El shell solo expande los alias que aparecen en la primera posición en una línea de comando.


2

usos de strace execve c functiontales como find command, Sin embargo, find uses exec functionno puede usar aliases, built-in shell commandetc.

Tu tienes que hacer:

strace /bin/rm -i ramesh

2

Para construir sobre la respuesta de Stéphane Chazelas, si define

alias strace="strace "

(con un espacio al final) luego el comando

strace rm ramesh

será procesado como

strace rm -i ramesh

Pero incluso esto funcionará solo para la primera palabra después de la strace, por lo que no se aplicaría directamente a su ejemplo (donde tiene opciones de intervención).  Pero si tu defines

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

entonces

my_strace rm ramesh

será procesado como

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

2

No hay alias aquí

Supongamos que tenemos la definición de alias alias rm='rm -i'en nuestro ~/.bashrc. El alias agrega la opción de preguntar antes de eliminar cada archivo:

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

No es culpa de straceque no haya usado el alias: no
tiene nada que ver con los alias.

En el comando

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

Las palabras rmy ./fileson solo argumentos para strace por ahora: el shell no puede expandir el alias rm, porque no puede saber que strace usará estos argumentos como comando más adelante.

En general, los alias de comando solo se pueden usar donde pueden estar los comandos.

Los alias son una característica del shell, y straceno utiliza un shell cuando llama al comando desde la línea de comandos. En su exec()lugar, usa los comandos y argumentos de su propia línea de comandos.

Dentro de strace, se llamará al comando con algo similar exec("rm", "file")y exec()se encontrará /bin/rmen PATH, sin usar un shell.

Shell explícito

Ahora, ¿por qué no incluir un shell en el 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 ... eso no funcionó. rmacaba de eliminar el archivo, sin el -iaviso.

Alias ​​interactivos

Los alias normalmente solo se habilitan en shells interactivos, líneas de comando reales en un terminal.
Con nuestro alias de ejemplo, es fácil ver por qué eso tiene sentido: si el rm -ialias se expandiera dentro de los scripts de shell, se colgarían al principio rmsin nadie allí para presionar y.

Los alias son controlados por la opción de shell expand_aliases. Podríamos establecer la opción con bash +O expand_aliases -c .... Pero eso no es suficiente, porque el shell no interactivo tampoco leerá ~/.bashrc. Eso significa que nuestro alias no solo está desactivado por la opción, sino que ni siquiera está definido.

Pretendiendo ser interactivo

La manera fácil de manejar ambas partes es usar la opción de línea de comando -ipara hacer que el shell finja que es interactivo:

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

Finalmente, -ise usó el alias!

Tenga en cuenta que normalmente no usaría shells con la -iopción de secuencias de comandos, incluso si desea tener sus alias disponibles, por ejemplo.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.