¿Cómo funciona la finalización automática de Bash?

9

Puedo entender que bash auto complete funciona para las utilidades estándar. Pero, ¿cómo funciona la finalización automática para programas personalizados como Oracle SQL Loader?

En el siguiente comando si tabula después control=, se completa automáticamente con el nombre del archivo de control:

sqlldr kshitiz/oracle@XE control=data.ctl data=data.csv bad=data.bad log=data.log

¿Cómo sabe que tiene que completar el archivo de control en ese punto y no otro archivo?

Kshitiz Sharma
fuente
2
La finalización de los parámetros se realiza con funciones. La mayoría de ellos están instalados en /etc/bash_completion.d. Vea también /etc/bash_completiony eche un vistazo a la producción de setcuánto ha crecido su entorno.
ott--
@ott ¿Qué debería estar buscando en esa ubicación? No puedo ver nada relacionado con sqlldr. Todo lo que tengo es: gdbus-bash-completion.sh gvfs-bash-completion.sh pk-completion.bash yum.bash. La salida de setes igual de interesante.
Kshitiz Sharma
También se podría hacer en algún script de /etc/profile.d. O tal vez tu .bash_profileo .bashrcfue modificado.
ott--
¿En qué se diferencian estas funciones de las funciones normales? ¿Y cómo hice para definir el mío para proporcionar autocompletado para un script personalizado? ¿Podría apuntar en la dirección correcta?
Kshitiz Sharma
1
@KshitizSharma, bash-completioncarga las terminaciones dinámicamente desde entonces 1.90. Proveedores: sqlldr<space><tab><enter>. Luego escribe complete -p sqlldr.
Evgeny Vereshchagin

Respuestas:

6

La finalización programable de Bash funciona analizando la línea de comando y descubriendo lo que se está completando:

  1. Algunos contextos se tratan especialmente, por ejemplo, la primera palabra de un comando se completa como un nombre de comando, lo que sigue a $se completa como un nombre de variable, etc.
  2. Fuera de estos contextos, bash intenta completar el argumento de un comando, y se aplica la configuración para el comando o si falla (que suele ser el caso) para el nombre base del comando.

Por ejemplo, después , bash completa los nombres de comando que comienzan con . Después , bash completa los nombres de variables que comienzan con . Después , bash aplica las reglas de finalización para el comando . Las reglas de finalización pueden especificar una categoría (usuario, variable, archivos, etc.), un patrón comodín para los nombres de archivo o una función o fragmento de código para ejecutar.sqllTabsqllsqlldr $aTabasqlldr Tabsqlldr

Las reglas de finalización están definidas por el completeincorporado. Bash no realiza un seguimiento de cuándo completese llamó al builtin o de qué script (si corresponde) estaba. La mayoría de las distribuciones envían el paquete bash-complete , que proporciona una serie de reglas para comandos comunes. Esto toma la forma de una serie de archivos de script que contienen llamadas a complete, con un script que debe leerse .bashrc(o /etc/bash.bashrcsi está implementado) para cargar todos estos scripts: generalmente . /etc/bash_completiones necesario para activar la finalización programable y cargar los scripts disponibles.

El paquete estándar no incluye soporte para sqlldr. Si tiene dicho soporte, debe provenir de una fuente diferente. Es posible que esta fuente haya dejado caer un archivo en un directorio similar /etc/bash_completion.do que haya venido con instrucciones para incluir algún código en su .bashrc. Puede usar complete -p sqlldrpara ver las reglas actuales para sqlldr; como se mencionó anteriormente, esto no le dirá de dónde se cargaron esas reglas.

Tcsh, zsh y fish tienen mecanismos algo similares (todos se inspiraron en tcsh) pero incorporaron diferentes capacidades, sintaxis y capacidades.

Gilles 'SO- deja de ser malvado'
fuente
Sí, no puede localizar dónde completese llamó. Pero puede encontrar el nombre del archivo de origen y el número de línea donde se define la función de finalización. complete -p sudo # outputs complete -F _sudo sudo, shopt -s extdebug, declare -F _sudo # outputs _sudo 3 /usr/share/bash-completion/completions/sudo. (Pero vea mi comentario sobre la finalización dinámica de la carga y complete -p).
Evgeny Vereshchagin
and the settings for the basename of the command are applied. No. Puede tener un compspecs diferente para datey /bin/date. La referencia dice : Si la palabra de comando es una ruta completa, primero se busca una compspec para la ruta completa. Si no se encuentra ninguna compspec para el nombre de ruta completo, se intenta encontrar una compspec para la porción que sigue a la barra final
Evgeny Vereshchagin