web-dev-qa-db-fra.com

Arrêter l’extension des caractères génériques Shell?

Existe-t-il un moyen pour un programme de ligne de commande compilé d'indiquer à bash ou csh qu'il ne souhaite pas que les paramètres génériques soient développés?

Par exemple, on peut vouloir une commande Shell comme:

foo *

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

60
hotpaw2

Non. Le développement a lieu avant que la commande soit réellement exécutée.
Vous pouvez uniquement désactiver le glob 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 *
86
c00kiemon5ter

Même s’il est vrai qu’une commande elle-même ne peut pas désactiver la segmentation, il est possible pour un utilisateur de dire à un shell Unix de ne pas globaliser une commande particulière. Ceci est généralement accompli en modifiant les fichiers de configuration d'un shell. En supposant que la commande foo soit présente le long du chemin de commande, les éléments suivants doivent être ajoutés au fichier de configuration approprié:

Pour les coquilles sh, bash et ksh:

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

Pour les shells csh et tcsh:

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

Pour le shell zsh:

alias foo='noglob foo'

Le chemin de commande ne doit pas être utilisé. Disons que la commande foo est stockée dans le répertoire ~/bin, alors ce qui précède deviendrait:

Pour les coquilles sh, bash et ksh:

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

Pour les shells csh et tcsh:

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

Pour le shell zsh:

alias foo='noglob ~/bin/foo'

Tous les éléments ci-dessus ont été testés sous OSX 10.9.2 ..__ d'Apple. Remarque: lors de la copie du code ci-dessus, veillez à ne pas supprimer les espaces. Ils peuvent être importants.

Mettre à jour:

Utilisateur geira a fait remarquer 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="$1";shift;$CMD "$@";set +f;}
alias foo='set -f;reset_expansion ~/bin/foo'

ce qui élimine le besoin de la fonction foo.

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

44
David Anderson

L'expansion est effectuée par le shell avant l'exécution de votre programme. Votre programme ne sait pas si une expansion s'est produite ou non. 

   set -o noglob

désactive l’extension dans le shell d’invocation, mais vous devez le faire avant vous appelez votre programme.

L'alternative consiste à citer vos arguments, par exemple.

foo "*"
7
Brian Agnew

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

La preuve (pa.py est un script très simple, qui affiche simplement 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
lesnik

Non, un shell de type Bourne exécute toujours globbing lorsque cela est approprié avant d'exécuter la commande. L'utilisateur doit citer ou échapper les arguments pour empêcher la suppression, tels que foo \*; le programme en cours d'exécution ne peut pas indiquer de préférence.

0
mrb