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

13

Ao tentar adicionar um pouco mais de detalhes a uma pergunta relacionada , percebi que não sabia como especificar qual dos tipos de palavras Bash disponíveis executar. De acordo com help typehá cinco tipos de palavras:

  • pseudônimo
  • palavra chave
  • função
  • construídas em
  • Arquivo

É possível que uma palavra tenha vários tipos ( trueé apenas um exemplo; seria uma palavra substituída mais comumente 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, pois tem precedência sobre todos os outros sinônimos. Forçar isso só seria útil quando o comando falhar se o alias não estiver definido.

    $ 
  • palavra-chave:

    $ 
  • função:

    $ 
  • construídas em:

    $ builtin true
  • Arquivo:

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

Soluções parciais :

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

    $ 'true'

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

l0b0
fonte

Respostas:

10

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

palavra - chave significa que é uma palavra que faz parte da sintaxe do shell. Esses são reconhecidos por meio de tokenização. A citação é suficiente para que o shell pare 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 mais cedo, e há mais tokens depois disso, onde você pode ter mais aliases, palavras-chave) ...

aliases (com exceção dos aliases zsh definidos com alias -gsão expandidos apenas na posição de comando), normalmente não estão em builtin the-alias.

funções têm precedência sobre builtins e builtins sobre comandos externos (e depois $PATHdecide qual usar).

Você pode forçar o builtin com:

builtin the-cmd and its args

(embora deva notar-se que não é um comando padrão).

Você pode desativar aliases citando-os (embora a versão citada também possa estar com alias em alguns shells).

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

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

A escrita while trueseria realmente impressa alias while truee não haveria como usar a whilepalavra - chave, pois citá-la desativaria o alias e a palavra-chave.

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

'whi'le whatever

Se houvesse um whilebuiltin (mas é claro que não existiria nos shells que possuem whilepalavra-chave), você escreveria:

builtin while whatever

E para chamar o whilecomando, você escreveria:

env while whatever

ou em zsh(quando não estiver em shemulação):

command while whatever 

(em outras conchas, commandapenas impede funções, não embutidas)

Ou

/full/path/to/while whatever

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

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

O qual, pelo menos no zsh, é válido (mas estúpido).

Stéphane Chazelas
fonte
A citação suprime a pesquisa de alias e a command pesquisa de função, mas nenhuma delas especifica qual dos sinônimos restantes será usado. Estou procurando uma maneira de especificar para executar apenas um sinônimo específico .
L0b0
@ l0b0 "command" suprime todos os apelidos, palavras-chave e incorporados.
Stéphane Chazelas
Quanto a fazer sentido, builtiné usado, por exemplo, no RVM para substituir cdum efeito agradável.
L0b0
Você está certo; e acabei de verificar que ele também suprime funções. +1.
L0b0
0

Um idioma extremamente útil para mim é o seguinte:

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 agrupado) ecoará as informações de depuração

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

Graham Nicholls
fonte
1
Como isso responde à pergunta?
L0b0