2017-03-16 4 views
6

Un des systèmes hérités a été mis à niveau vers bash4 et la plupart de ses scripts ont cessé de fonctionner. Je l'ai réduit à la façon dont les accolades sont élargies dans un <(cmdA ...|cmdB ... file{1,2}|cmdZ ...).Pourquoi bash4 élargit différemment les accolades?

Pour illustrer la différence mieux:

AVANT (bash 3.2.25):

[[email protected]:~]$ bash -version|head -1 
GNU bash, version 3.2.25(1)-release (x86_64-redhat-linux-gnu) 
[[email protected]:~]$ cat <(echo sort file{1,2}) 
sort file1 
sort file2 
[[email protected]:~]$ join <(sed 's/\r//g;s/^[^:]*://' file{1,2}|LANG=C sort) 
[[email protected]:~]$ 

APRÈS (bash 4.1.2):

[[email protected]:~]$ bash --version|head -1 
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu) 
[[email protected]:~]$ cat <(echo sort file{1,2}) 
sort file1 file2 
[[email protected]:~]$ join <(sed 's/\r//g;s/^[^:]*://' file{1,2}|LANG=C sort) 
join: missing operand after `/dev/fd/63' 
Try `join --help' for more information. 
[[email protected]:~]$ 

Est-il un « Hard- codé "(et attendu?) changement fait pour bash4? Ou est-ce que le comportement de cette extension est contrôlé par certains paramètres de bash (comme set -B/set +B) et peut être ramené en mode old/legacy/bash3? Je préférerais changer un commutateur à l'échelle du shell (au lieu de devoir réécrire une pile de scripts).

Si cette (bash3) « fonction » a été coupée pendant une bugfix ou d'amélioration - Je suis surpris, parce que le vieux (bash3) syntaxe permet d'économiser une tonne sur le typage ...

+3

Oh, attends. Vous vous attendez à ce que deux substitutions de processus * différentes soient générées, et non deux arguments à 'sed'? Je ne sais pas si c'était ** toujours ** conforme à un comportement correct et documenté ... c'est-à-dire, AFAIK, votre code dépendait d'un bug. –

+0

@CharlesDuffy - ça a toujours fonctionné (pour moi et les scripts) jusqu'à la mise à niveau de bash4 - le '<(cmd {a, b})' s'est développé en deux <(cmd a) <(cmd b) 'et a été passé dans join/etc Ces scripts utilisent intensivement cette fonctionnalité, l'imbriquant à plusieurs niveaux et les scripts sont testés (je ne voulais pas le toucher avec mes gros doigts et générer de nouvelles erreurs). – Vlad

+3

@Vlad Cela ressemble à un bug, qu'ils ont corrigé dans Bash 4. Vous devriez vous attendre à ce que la commande dans '<(...)' soit analysée comme n'importe quelle autre commande, donc '<(cmd {a, b}) 'devrait être équivalent à' <(cmd ab) '. – Barmar

Répondre

4

Le comportement d'origine était non documenté (et contrairement à la règle générale que le code inclus dans une substitution de processus, comme un sous-shell ou un contexte similaire, analyse de la même manière dans laquelle il se serait comporté en dehors de celui-ci).

En tant que tel, c'était un bug, pas une caractéristique. Ce bug a été corrigé dans bash-4.0-alpha. Citant l'entrée CHANGES:

rr. L'expansion de l'accolade permet désormais aux substitutions de processus de passer inaperçues.

Aucun indicateur d'exécution permettant d'annuler cette modification n'est disponible.

+1

Je creusais dans la même direction entre temps, trouvé un autre utilisateur affecté (http://wiki.bash-hackers.org/syntax/expansion/brace), puis trouvé la même entrée dans CHANGES et tous les commits git qui ont conduit à "commenter bash-20080724 instantané". Pour la simplicité de mon objectif - Je vais recompiler le bash4 personnalisé pour ma boîte tout en retournant seulement le changement de priorité, puis revérifier les scripts. Triste, il n'a pas été exposé à des drapeaux d'exécution pour simplifier mon objectif. Laissez-moi upvote toutes les réponses et merci! – Vlad