Arrêter l'expansion des caractères génériques de shell?

y a-t-il un moyen pour un programme compilé en ligne de commande de dire à bash ou csh qu'il ne veut pas de caractères génériques dans ses paramètres étendus?

par exemple, on peut vouloir une commande shell comme:

foo *

pour simplement retourner la valeur numérique ASCII de ce caractère.

52
demandé sur hotpaw2 2012-07-12 20:30:47

5 réponses

Pas de. L'extension a lieu avant que la commande ne soit réellement exécutée.

Vous ne pouvez désactiver le glob qu'avant d'exécuter la commande ou en citant l'étoile.

$ # quote it
$ foo '*'

$ # or escape it
$ foo \*

$ # or disable the glob (noglob)
$ set -f
$ foo *
78
répondu c00kiemon5ter 2017-05-30 23:41:36

S'il est vrai qu'une commande elle-même ne peut pas désactiver globbing, il est possible pour un utilisateur de dire à un shell Unix de ne pas exécuter une commande particulière. Ceci est généralement réalisé en éditant les fichiers de configuration d'un shell. En supposant que la commande foo puisse être trouvée le long du chemin de commande, il faudrait ajouter ce qui suit au fichier de configuration approprié:

pour les coquilles sh, bash et ksh:

alias foo='set -f;foo';foo(){ command foo "$@";set +f;}

pour les csh et réservoirs tcsh:

alias foo 'set noglob;\foo \!*;unset noglob'

pour la coque zsh:

alias foo='noglob foo'

il n'est pas nécessaire d'utiliser le chemin de commande. Supposons que la commande foo soit stockée dans le répertoire ~ / bin, alors la commande ci-dessus deviendra:

pour les coquilles sh, bash et ksh:

alias foo='set -f;foo';foo(){ ~/bin/foo "$@";set +f;}

pour les réservoirs csh et tcsh:

alias foo 'set noglob;$home/bin/foo \!*;unset noglob'

pour la coque zsh:

alias foo='noglob ~/bin/foo'

Tout ce qui précède a été testé avec L'OSX 10.9.2 D'Apple. Note: lors de la copie du code ci-dessus, attention à ne pas supprimer d'espaces. Ils peuvent être importants.

mise à jour:

Utilisateur la nouvelle loi a souligné que, dans le cas d'un shell bash

alias foo='set -f;foo';foo(){ ~/bin/foo "$@";set +f;}

pourrait être remplacé par

reset_expansion(){ CMD="";shift;$CMD "$@";set +f;}
alias foo='set -f;reset_expansion ~/bin/foo'

qui élimine la nécessité de la fonction foo.

certains sites Web utilisés pour créer ce document:

41
répondu David Anderson 2017-05-23 11:47:17

l'extension est exécutée par le shell avant que votre programme ne soit lancé. Votre programme n'a aucune idée si l'expansion a eu lieu ou non.

   set -o noglob

désactivera l'extension dans l'interpréteur de commandes, mais vous devrez faire cela avant vous invoquez votre programme.

l'alternative est de citer vos arguments par exemple

foo "*"
7
répondu Brian Agnew 2018-06-01 11:44:02

attention: s'il n'y a pas de noms correspondant au masque, bash passe l'argument tel quel, sans extension!

preuve (pa.py est un script très simple, qui n'imprime que ses arguments):

 $ ls
f1.cc  f2.cc  pa.py
 $ ./pa.py *.cc
['./pa.py', 'f1.cc', 'f2.cc']
 $ ./pa.py *.cpp
['./pa.py', '*.cpp']
1
répondu lesnik 2015-07-15 01:25:47

Pas de. Un shell de style Bourne exécute toujours globbing s'il y a lieu avant d'exécuter la commande. L'utilisateur doit citer ou échapper aux arguments pour éviter le globbing, comme foo \* ; le programme en cours d'exécution ne peut pas indiquer une préférence.

0
répondu mrb 2012-07-12 16:34:14