Como forçar uma palavra Bash a referenciar um apelido, função, arquivo, etc?

13

Ao tentar adicionar um pouco mais de detalhes a um question , percebi que não sei como especificar qual dos tipos de palavras Bash disponíveis para executar. De acordo com help type , existem cinco tipos de palavras:

  • alias
  • palavra-chave
  • função
  • incorporado
  • arquivo

É possível que uma palavra tenha vários tipos ( true é apenas um exemplo; uma palavra mais comumente substituída seria cd ):

$ type -a true
true is a shell builtin
true is /bin/true

Como você força a execução de um sinônimo específico? Até agora, em ordem de precedência:

  • alias: Este é um caso especial, uma vez que tem precedência sobre todos os outros sinônimos. Forçar isso só seria útil quando o comando falhasse se o alias não estivesse definido.

    $ 
    
  • palavra-chave:

    $ 
    
  • função:

    $ 
    
  • incorporado:

    $ builtin true
    
  • arquivo

    :

    $ command true
    $ $(which true)
    $ /bin/true
    

Soluções parciais :

  • Citar uma palavra exclui aliases e palavras-chave. Isto é,

    $ 'true'
    

    executará apenas a função, interna ou arquivo.

por l0b0 22.01.2013 / 13:32

2 respostas

10

O que você está perguntando não faz muito sentido.

palavra-chave significa que é uma palavra que faz parte da sintaxe do shell. Aqueles são reconhecidos através de tokenising. Citá-los é o suficiente para o shell parar de reconhecer.

É possível alias uma palavra-chave na maioria dos shells. Portanto, os aliases têm precedência sobre as palavras-chave (na verdade, elas são expandidas antecipadamente e há mais tokenising depois disso, onde você pode ter mais aliases, palavras-chave) ...

aliases (com a exceção de aliases zsh definidos com alias -g são apenas expandidos na posição de comando), então normalmente não em builtin the-alias .

funções têm precedência sobre builtins e builtins sobre comandos externos (e então $PATH decide qual usar).

Você pode forçar o builtin com:

builtin the-cmd and its args

(embora deva ser notado, não é um comando padrão).

Você pode desabilitar os aliases citando-os (embora a versão citada também possa ser aliada em alguns shells).

Então, por exemplo (aqui sintaxe zsh), em:

'while'() echo function while
alias 'while=echo alias while'

A gravação de while true produziria realmente alias while true e não haveria como usar a palavra-chave while , já que citá-la desativaria o alias e a palavra-chave.

Você chamaria a função while com, por exemplo:

'whi'le whatever

Se houvesse um while embutido (mas é claro que não funcionariam naqueles shells que tivessem while palavra-chave), você o escreveria:

builtin while whatever

E para chamar o comando while , você escreveria:

env while whatever

ou em zsh (quando não em sh emulação):

command while whatever 

(em outros shells, command apenas previne funções, não builtins)

Ou

/full/path/to/while whatever

Claro, nada o impede de fazer coisas ainda mais idiotas como:

alias 'while=while "w"hile; do'
"while"() { while "whi"le; done; }

Qual, pelo menos em zsh, é válido (mas estúpido).

    
por 22.01.2013 / 14:28
0

Uma linguagem extremamente útil para mim é esta:

FALSE=1; TRUE=0
DEVEL_FLAG=$FALSE
...
in_development() { return $DEVEL_FLAG ; }
cd()
{
 if in_development ; then # -D argument to script toggles development flag
   echo "Would run cd $*"
  else
   builtin cd "$@"
 fi
}

Agora, se eu executar o script com -D especificado, o modo de desenvolvimento será ativado, e o cd (ou qualquer outro comando "wrapped") exibirá as informações de depuração

Isso é especialmente útil com scripts que executam o ssh. Claro que eu poderia alternar set-x, mas isso é mais útil e legível para mim.

    
por 06.09.2013 / 15:17

Tags