Tengo un alias
conjunto para mi rm
comando. Si ejecuto el alias
comando, esto es lo que obtengo como salida.
alias rm='rm -i'
Ahora, cuando ejecuto el rm
comando 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 strace
comando 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 rm
comando. Elimina el archivo sin preguntar al usuario.
Entonces, ¿ strace
ignora alias como este? Si es así, ¿por qué es así?
EDITAR:
No estoy seguro, si esto tiene algo que ver pero type -a rm
me da la salida como,
rm is aliased to `rm -i'
rm is /bin/rm
Entonces, ¿está considerando /bin/rm
en este caso por qué no se solicita al usuario antes de la eliminación?
strace
no ignora los alias, porque eso implicaría que había algo que ignorar en primer lugar. Un alias es una característica del shell.strace
es un programa diferente, y dentrostrace
del 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.strace
un alias, debestrace
usar el shell, que implementa el alias. Hay algunos enfoques que se pueden tomar para hacer eso:strace -p $$ &
ostrace bash
ostrace sh -c 'rm ramesh'
(la última voluntad también ignoran el alias, pero por una razón completamente diferente.)Respuestas:
strace
no funcionarm -i
por la misma razón que: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:
Las conchas lo expanden a:
y eso se somete a otra ronda de interpretación, en ese caso conduce a la ejecución del
whatever
comando.los alias solo se expanden cuando se encuentran en la posición de comando (como la primera palabra de una línea de comando).
zsh
admite alias globales .Podrías hacerlo:
Pero no querrás, ya que eso significaría que:
saldría
rm -i
por ejemplo.fuente
strace
usa laPATH
variable 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, porstrace
lo tanto, lo ignora.Correr
strace strace rm
es bastante esclarecedor, además de ser interesantemente recursivo.fuente
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.fuente
usos de strace
execve c function
tales comofind command
, Sin embargo,find uses exec function
no puede usaraliases
,built-in shell command
etc.Tu tienes que hacer:
fuente
Para construir sobre la respuesta de Stéphane Chazelas, si define
(con un espacio al final) luego el comando
será procesado como
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 definesentonces
será procesado como
fuente
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:No es culpa de
strace
que no haya usado el alias: notiene nada que ver con los alias.
En el comando
Las palabras
rm
y./file
son solo argumentos para strace por ahora: el shell no puede expandir el aliasrm
, 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
strace
no utiliza un shell cuando llama al comando desde la línea de comandos. En suexec()
lugar, usa los comandos y argumentos de su propia línea de comandos.Dentro de
strace
, se llamará al comando con algo similarexec("rm", "file")
yexec()
se encontrará/bin/rm
en PATH, sin usar un shell.Shell explícito
Ahora, ¿por qué no incluir un shell en el
strace
comando?Hmm ... eso no funcionó.
rm
acaba de eliminar el archivo, sin el-i
aviso.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 -i
alias se expandiera dentro de los scripts de shell, se colgarían al principiorm
sin nadie allí para presionary
.Los alias son controlados por la opción de shell
expand_aliases
. Podríamos establecer la opción conbash +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
-i
para hacer que el shell finja que es interactivo:Finalmente,
-i
se usó el alias!Tenga en cuenta que normalmente no usaría shells con la
-i
opción de secuencias de comandos, incluso si desea tener sus alias disponibles, por ejemplo.fuente