Eu tenho um alias
conjunto para o meu rm
comando. Se eu executar o alias
comando, é isso que recebo como saída.
alias rm='rm -i'
Agora, quando executo o rm
comando, ele funciona bem como esperado.
rm ramesh
rm: remove regular empty file `ramesh'? y
Agora, eu estava aprendendo sobre as chamadas do sistema que estão sendo chamadas quando executo um comando. Para isso, fiquei sabendo do strace
comando a partir daqui, que lista os arquivos que estão sendo chamados quando executo algum comando. O comando é como abaixo.
strace -ff -e trace=file rm ramesh 2>&1
O comando funciona perfeitamente bem, exceto que ignora meus aliases que eu tenho para o meu rm
comando. Exclui o arquivo sem avisar o usuário.
Então, strace
ignora aliases como este? Se sim, por que é assim?
EDITAR:
Não tenho certeza, se isso tem algo a ver, mas type -a rm
me fornece a saída como,
rm is aliased to `rm -i'
rm is /bin/rm
Portanto, /bin/rm
neste caso, é por isso que o usuário não é solicitado antes da exclusão?
strace
não ignora aliases, porque isso implicaria que havia algo a ser ignorado em primeiro lugar. Um alias é um recurso do shell.strace
é um programa diferente e, dentrostrace
do conceito de alias, não existe; portanto, não há nada a ignorar. A API fornecida pelo kernel para a execução de programas também não possui um conceito de aliases; portanto, não há como o shell diferenciar os aliases, mesmo que desejasse.strace
um alias, precisarástrace
do shell, que implementa o alias. Há algumas abordagens que você pode tomar para fazer isso:strace -p $$ &
oustrace bash
oustrace sh -c 'rm ramesh'
(a última vontade também ignoram o alias, mas por uma razão completamente diferente.)Respostas:
strace
não é executadorm -i
pelo mesmo motivo que:não sai
rm -i
.Os aliases são um recurso de alguns shells para permitir que algumas strings sejam substituídas automaticamente por outras quando encontradas na posição de comando.
No:
As conchas expandem isso para:
e que passa por outra rodada de interpretação, nesse caso levando à execução do
whatever
comando.os aliases são expandidos apenas quando encontrados na posição de comando (como a primeira palavra de uma linha de comando).
zsh
suporta aliases globais .Você poderia fazer:
Mas você não gostaria, pois isso significaria que:
produziria,
rm -i
por exemplo.fonte
strace
usa aPATH
variável de ambiente para localizar o programa a ser rastreado, em vez de executá-lo através do shell (o que atrapalharia a saída). Um alias do shell não é um programa, é um recurso do shell e, portanto, ostrace
ignora.Correr
strace strace rm
é bastante esclarecedor, além de ser curiosamente recursivo.fonte
Um alias é um recurso do seu shell. No entanto, strace executa o comando diretamente (usando
execve
, provavelmente), o que não envolve o shell. (Se o strace executasse o comando fornecido por meio do shell, a saída do strace conteria todos os syscalls de execução do shell, e não apenas os do processo de interesse.)Além disso, quando você executa
strace rm ramesh
, o shell interativo não tenta substituir seu alias nos argumentos a serem rastreados, porque isso seria terrivelmente confuso para todos. O shell apenas expande aliases que aparecem na primeira posição em uma linha de comando.fonte
O Strace usa
execve c function
comofind command
No entanto,find uses exec function
você não pode usaraliases
,built-in shell command
etc.Você tem que fazer:
fonte
Para aproveitar a resposta de Stéphane Chazelas, se você definir
(com um espaço no final), então o comando
será processado como
Mas mesmo isso funcionará apenas para a primeira palavra após a
strace
, portanto, não se aplicaria diretamente ao seu exemplo (onde você tem opções intermediárias). Mas se você definirentão
será processado como
fonte
Nenhum alias aqui
Vamos assumir que temos a definição de alias
alias rm='rm -i'
em nossa~/.bashrc
. O alias adiciona a opção de solicitação antes de remover cada arquivo:Não é culpa
strace
disso que ele não usou o pseudônimo: nãotem nada a ver com pseudônimos.
No comando
As palavras
rm
e./file
são apenas argumentos para strace por enquanto - o shell não pode expandir o aliasrm
, porque não pode saber que strace usará esses argumentos como comando posteriormente.Em geral, os aliases de comando podem ser usados apenas onde os comandos podem estar.
Aliases são um recurso do shell e
strace
não usam um shell quando chama o comando na linha de comando. Emexec()
vez disso, ele usa os comandos e argumentos de sua própria linha de comando.Dentro de
strace
, o comando será chamado com algo semelhanteexec("rm", "file")
eexec()
encontrará/bin/rm
no PATH - sem usar um shell.Shell explícito
Agora, por que não incluir um shell no
strace
comando?Hmm ... isso não funcionou.
rm
acabou de excluir o arquivo, sem o-i
prompt.Aliases interativos
Aliases normalmente são ativados apenas em shells interativos, linhas de comando reais em um terminal.
Com o nosso exemplo de alias, é fácil ver por que isso faz sentido: se o
rm -i
alias fosse expandido dentro de scripts shell, eles seriam interrompidos no iníciorm
sem ninguém lá para pressionary
.Os aliases são controlados pela opção shell
expand_aliases
. Poderíamos definir a opção combash +O expand_aliases -c ...
. Mas isso não é suficiente, porque o shell não interativo também não lerá~/.bashrc
. Isso significa que nosso alias não é apenas desativado pela opção, mas também nem é definido.Fingindo ser interativo
A maneira mais fácil de lidar com ambas as partes é usar a opção de linha de comando
-i
para fazer o shell fingir que é interativo:Finalmente, o
-i
alias foi usado!Observe que você normalmente não usaria shells executados com a
-i
opção de script, mesmo que desejasse ter seus aliases disponíveis, por exemplo.fonte