Ordem dos executáveis iniciados no bash

9

Se eu executar o comando test no bash, test (avalia a expressão condicional), o utilitário interno será iniciado:

$ type test
test is a shell builtin
$ type -a test
test is a shell builtin
test is /usr/local/bin/test
test is /usr/bin/test
$ 

No entanto, como visto na saída de type -a test acima, há outro test no diretório / usr / local / bin e outro no diretório / usr / bin. Como os executáveis são ordenados, ou seja, os comandos internos são sempre preferidos e, em seguida, o restante dos comandos depende da ordem do diretório na variável $ PATH? Além disso, é possível alterar a ordem dos executáveis iniciados, por ex. se eu digitar test , então / usr / bin / test é iniciado em vez de bash-builtin test ?

    
por Martin 30.05.2014 / 00:33

2 respostas

18

A prioridade mais alta é bash alias, depois builtins especiais (somente no modo POSIX), depois funções, depois builtins, então uma busca em $PATH .

Para executar um builtin, use builtin test .
Para executar um aplicativo externo, use um caminho explícito: /bin/test .
Para ignorar funções e aliases, use command test .
Para ignorar apenas alias, use \test ou qualquer outro tipo de expansão.

É possível desativar / ativar um embutido com enable test .

(Atualizado de acordo com comentários abaixo)
(Corrigida a edição incorreta de admin que o bash tem disable embutido - na verdade, existe apenas enable )

    
por 30.05.2014 / 01:00
5

Comandos incorporados são sempre preferidos aos comandos externos. A lógica é que o comando interno é mais rápido (e, em alguns casos, como cd ou test -o BASH_OPTION , somente o comando interno pode ter o efeito desejado).

Às vezes, o comando externo pode ter recursos que o shell embutido não possui. Nesse caso, você pode chamar o comando externo dando um caminho explícito (ou seja, contendo uma barra) (isso ignora qualquer preocupação sobre o pedido em $PATH ). Se você não deseja codificar o caminho externo, mas deseja impedir o uso do incorporado, use "$(type -P test)" (nota capital P ) no bash, "$(whence -p test)" no ksh e =test em zsh. Outra maneira de forçar o uso de um comando externo é usar o command builtin ( command -p test … ) ou passar pelo utilitário env ( env test … ).

No zsh, você pode desativar um arquivo incorporado com disable test . Isso é permanente (para o shell ou subshell atual) até que o builtin seja reativado com enable test . No bash, você pode fazer o mesmo com enable -n test para desativar e enable test para reativar.

Você pode usar um alias ou uma função para forçar a execução de um comando diferente, por exemplo, alias test=/usr/bin/test ou test () { /usr/bin/test "$@"; } . Se você tiver esse alias, poderá impedir seu uso citando qualquer parte dele, por exemplo, \test executará a função normal / pesquisa interna / externa. Observe que, dependendo do shell e suas configurações, as definições de alias em uma função podem ser expandidas quando uma função é lida ou quando é executada. Se você definiu uma função, você pode usar command test para evitar a pesquisa de função, bem como a pesquisa de alias (então aqui o test builtin será invocado a menos que seja desativado).

    
por 30.05.2014 / 02:14