¿Cómo forzar que una palabra Bash haga referencia a un alias, función, archivo, etc.?

13

Al intentar agregar un poco más de detalle a una pregunta relacionada , me di cuenta de que no sé cómo especificar cuál de los tipos de palabras Bash disponibles ejecutar. Según help typehay cinco tipos de palabras:

  • alias
  • palabra clave
  • función
  • incorporado
  • archivo

Es posible que una palabra tenga varios tipos ( truees solo un ejemplo; una palabra más comúnmente anulada sería cd):

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

¿Cómo se fuerza la ejecución de un sinónimo específico? Hasta ahora, en orden de precedencia:

  • alias: este es un caso especial ya que tiene prioridad sobre todos los demás sinónimos. Forzar esto solo sería útil cuando el comando fallara si el alias no está definido.

    $ 
  • palabra clave:

    $ 
  • función:

    $ 
  • incorporado:

    $ builtin true
  • archivo:

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

Soluciones parciales :

  • Citar una palabra excluye alias y palabras clave. Es decir,

    $ 'true'

    ejecutará solo la función, incorporada o archivo.

l0b0
fuente

Respuestas:

10

Lo que preguntas realmente no tiene mucho sentido.

palabra clave significa que es una palabra que forma parte de la sintaxis del shell. Esos se reconocen a través de la tokenización. Citarlos es suficiente para que el shell deje de reconocer.

Sin embargo, es posible alias una palabra clave en la mayoría de los shells. Por lo tanto, los alias tienen precedencia sobre las palabras clave (en efecto, se expanden temprano, y luego hay más tokenización donde puede tener más alias, palabras clave) ...

alias (con la excepción de los alias zsh definidos con alias -gsolo se expanden en la posición del comando), por lo que normalmente no están en builtin the-alias.

las funciones tienen precedencia sobre las incorporadas, y las incorporadas sobre los comandos externos (y luego $PATHdecide cuál usar).

Puede forzar la construcción con:

builtin the-cmd and its args

(aunque debe tenerse en cuenta que no es un comando estándar).

Puede deshabilitar los alias entre comillas (aunque la versión citada también podría tener alias en algunos shells).

Entonces, por ejemplo (aquí sintaxis zsh), en:

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

La escritura while truerealmente generaría resultados alias while true, y no habría forma de usar la whilepalabra clave, ya que si se cita deshabilitaría tanto el alias como la palabra clave.

Llamaría a la whilefunción con, por ejemplo:

'whi'le whatever

Si hubiera un whileincorporado (pero, por supuesto, no lo haría en esos shells que tienen una whilepalabra clave), lo escribiría:

builtin while whatever

Y para llamar al whilecomando, escribirías:

env while whatever

o en zsh(cuando no está en shemulación):

command while whatever 

(en otros shells, commandsolo previene funciones, no incorporadas)

O

/full/path/to/while whatever

Por supuesto, nada te impide hacer cosas aún más tontas como:

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

Lo cual, al menos en zsh es válido (pero estúpido).

Stéphane Chazelas
fuente
Las citas suprimen la búsqueda de alias y command suprimen la búsqueda de funciones, pero ninguna de ellas especifica cuál de los sinónimos restantes se utilizará. Estoy buscando una manera de especificar para ejecutar solo un sinónimo específico .
l0b0
@ l0b0 "comando" suprime todos los alias, palabras clave y valores incorporados.
Stéphane Chazelas
En cuanto a tener sentido, builtinse utiliza, por ejemplo, en RVM para anular cdun efecto agradable.
l0b0
Tienes razón; y acabo de verificar que también suprime las funciones. +1.
l0b0
0

Un modismo extremadamente útil para mí es este:

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
}

Ahora, si ejecuto el script con -D especificado, el modo de desarrollo se activa y el cd (o cualquier otro comando envuelto) repite la información de depuración

Esto es especialmente útil con scripts que ejecutan ssh. Claro que podría alternar set -x, pero esto es más útil y legible para mí.

Graham Nicholls
fuente
1
¿Cómo responde esto a la pregunta?
l0b0