5 votes

Echapper les slashs en bash complet

J'essaie d'utiliser la fonction bash complete pour afficher les différentes options d'une commande.

J'ai des problèmes quand une option contient un chemin comme dans -F/dev/null .

Actuellement, j'utilise

#!/bin/bash

_xyz-completion ()
{
  local cur

  COMPREPLY=()   # Array variable storing the possible completions.
  cur=${COMP_WORDS[COMP_CWORD]}

  case "$cur" in
    -*)
    COMPREPLY=( $( compgen -W "-oOption1 -F/dev/null" -- $cur ) )
    ;;
  esac

  return 0
}

complete -F _xyz-completion -o filenames xyz

Si -F a déjà été tapé, alors un Tab l'achève avec succès.

Mais si seulement - a été tapé, puis un Tab montre

null -oOption1

Mais je m'attends à voir

-F/dev/null -oOption1

J'ai déjà essayé -F\/dev\/null , -F//dev//null , "-F/dev/null" y -F\\\/dev\\\/null

Il semble qu'il s'agisse uniquement d'un problème d'affichage, car l'achèvement lui-même fonctionne comme prévu.

Je ne vois pas comment échapper de manière appropriée les slashs dans `-F/dev/null`.


Pour commenter les commentaires :

1)

Peu importe, c'est aussi un problème si -F est remplacé par une non-option comme -Q. - Benjamin W.

Ce n'est pas un problème, que le -F semble être une option pour complete lui-même, car il échoue même si je le change en xOPTION1 xF/dev/null

2)

Je me demande ce que compgen -W "-oOption1 -F/dev/null" -- - affiche pour vous.

Il affiche (comme prévu)

-oOption1
-F/dev/null

Comme indiqué, -F s'achève avec succès sur -F/dev/null

3voto

nitram Points 500

Si vous retirez le -o filenames l'option de complete votre exemple fonctionne comme prévu. Ce qui est logique puisque les compléments ne sont pas des noms de fichiers. Ceci avec bash version 5.0.2(1).

Donc :

#!/bin/bash

_xyz-completion ()
{
  local cur

  COMPREPLY=()   # Array variable storing the possible completions.
  cur=${COMP_WORDS[COMP_CWORD]}

  case "$cur" in
    -*)
    COMPREPLY=( $( compgen -W "-oOption1 -F/dev/null" -- $cur ) )
    ;;
  esac

  return 0
}

complete -F _xyz-completion xyz

Le fait de tronquer une partie de l'achèvement lorsqu'il y a des barres obliques semble être un bogue. Et ce n'est qu'au moment de l'affichage des choix que la complétion réelle fonctionne correctement.

EDITAR:

Après avoir examiné la question de plus près, le filenames est utilisée pour l'échappement des chaînes de caractères qui pourraient contenir des espaces ou d'autres caractères de rupture. En fait, elle nettoie les noms de fichiers pour l'interpréteur de commandes. De l'option Page de manuel de l'achèvement programmable intégré

-o filenames :

Indique à Readline que le compspec génère des noms de fichiers, de sorte qu'il peut effectuer tout traitement spécifique aux noms de fichiers (comme l'ajout d'une barre oblique aux noms de répertoires, la citation de caractères spéciaux ou la suppression des espaces de fin). Cette option est destinée à être utilisée avec les fonctions shell spécifiées avec -F.

Apparemment, cela inclut le retrait de tout ce qui se trouve avant et après la dernière barre oblique.

EDIT2 :

Voici un commentaire du source readline que bash utilise pour la complétion des noms de fichiers. Je l'ai récupéré dans le répertoire de bash à l'adresse suivante https://git.savannah.gnu.org/git/bash.git ). Le maître, donc 5.0 patch 3 au moment de la rédaction.

./lib/readline/complete.c ligne 697

/* Return the portion of PATHNAME that should be output when listing
   possible completions.  If we are hacking filename completion, we
   are only interested in the basename, the portion following the
   final slash.  Otherwise, we return what we were passed.  Since
   printing empty strings is not very informative, if we're doing
   filename completion, and the basename is the empty string, we look
   for the previous slash and return the portion following that.  If
   there's no previous slash, we just return what we were passed. */
static char *
printable_part (char *pathname)

Pour la complétion de nom de fichier, il veut seulement imprimer le nom de base, tout ce qui se trouve après la dernière barre oblique.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X