2017-03-29 9 views
1

Dans toutes les coquilles suivantes:utiliser portably caractères spéciaux dans le développement des paramètres, avec ou sans guillemets doubles

  • bash
  • ksh
  • zsh
  • tiret

et sans un moyen d'influencer le choix du shell ou de shell paramètres, mon but est d'utiliser la valeur de chaîne par défaut (y!) chaque la variable nommée x est unset ou null. Par exemple, je souhaite que l'interpréteur exécute l'extension de paramètre produisant (y!)y représente un texte n'impliquant aucun caractère spécial. Alors, naïvement,

${x:-(y!)} 

Il peut y avoir des guillemets doubles. Un certain nombre de différences deviennent alors apparentes, parmi les coques interprétant ceci ou une variation. Dans une tentative de portabilité de l'approche, j'ai essayé des variantes en ajoutant 0 à \. J'ai aussi essayé les effets des espaces, mais je vais exclure cela pour l'instant.

${x:-(y!)}, ... , ${x:-\(y\!\)} 

L'une des différences indiquées par les obus serait, je suppose, être lié à surcharge des ! pour les événements de l'histoire d'une coquille. (Essayez !echo dans zsh.) D'autres différences subsistent lorsqu'une variante se produit entre guillemets. Une solution fonctionnerait idéalement entre guillemets, car je ne peux pas vraiment s'attendre à ce qu'un schéma ne soit pas utilisé dans ce contexte.

Par ex, étant donné COMAND echo "$0: ${x:-\(y\!\)}", à savoir, avec tous (, !, et ) précédé par \, les coquilles répondent:

-bash: \(y\!\) 
ksh: \(y\!\) 
zsh: \(y!\) 
dash: \(y\!\) 

Ainsi, la Z Shell supplie de différer. Il se trouve que ce qui suit semble fonctionner aussi bien dans bash, ksh, zsh, et tableau de bord:

$ echo "${x:-$(echo \(y\!\))}" 
(y!) 

Mais impliquant une autre substitution de commande (echo, même si intégré()?) Semble exagéré. Y a-t-il un meilleur moyen? Du tout? Suis-je manque quelque chose?

(zsh semble utiliser !{...}, donc pas \, à « isoler une référence historique de caractères adjacents (le cas échéant) » (zshexpn (1)). Peut-être qui explique pourquoi il réagit différemment?)

+0

@Stephane Chazelas Je pense que vous êtes la bonne personne pour répondre à cette question - et sera une chance pour nous d'apprendre –

+2

Que diriez-vous 'y = '(y!)'; echo "$ {x: -" $ y "}" '? Les shells conformes à POSIX devraient étendre cela à '(y!)' Si 'x' est unset ou null. –

+0

@BenjaminW., L'idée serait tout à fait o.K. pour mes propres scripts (chaque fois qu'il n'y a rien d'autre à développer, de sorte que '' 'ing suffise comme suggéré). Une certaine discipline lors du choix des noms pour «y» pourrait même entraîner une amélioration. Cependant, je ne suis pas sûr que je puisse l'offrir comme une procédure généralement applicable d'utilisation de l'expansion et des guillemets, mais cela pourrait fonctionner avec la persuasion supplémentaire de certaines remarques impliquant des raisons "pratiques" et "techniques". – B98

Répondre

1

En utilisant le code de octal pour le ! ombles semble fonctionner:

/bin/echo -e "'${x:-(y\0041)}'" 

Les echo BUILTIN commandes pour les différentes coques sont incompatibles, (deux nécessitent l'interrupteur -e, mais dash ne comprend pas) , donc /bin/echo est plus fiable. Testez les quatre coquilles:

unset x 
for f in dash bash zsh ksh ; do 
    echo -en "$f:\t" 
    $f -c "/bin/echo -e \"'\${x:-(y\0041)}'\"" 
done 

Sortie:

dash: '(y!)' 
bash: '(y!)' 
zsh: '(y!)' 
ksh: '(y!)' 
+0

Les commandes 'echo' sont en effet inconsistantes. Par exemple, je vois 'bash: \t -e '(y \ 0041)'' sur un Mac. Mais c'est une autre indication pour déplacer l'expansion vers l'extérieur. – B98