2017-03-16 4 views
6

Eines der Legacy-Systeme wurde auf bash4 aktualisiert und die meisten seiner Skripte funktionieren nicht mehr. Ich habe es darauf beschränkt, wie eine geschweifte Klammern innerhalb einer <(cmdA ...|cmdB ... file{1,2}|cmdZ ...) erweitert werden.Warum erweitert bash4 geschweifte Klammern anders?

Zur Veranschaulichung der Unterschied besser:

VOR (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]:~]$ 

AFTER (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]:~]$ 

Ist es ein „Hard- codiert "(und erwartet?) Änderung für bash4 gemacht? Oder wird das Verhalten dieser Erweiterung durch einige Bash-Level-Einstellungen (wie set -B/set +B) gesteuert und kann zurück in den alten/legacy/bash3-Modus geschaltet werden? Ich würde lieber einen Shell-weiten Schalter wechseln (statt einen Stapel von Skripten neu schreiben zu müssen).

Wenn diese (bash3) „Feature“ wurde während einer Bugfix oder Verbesserung abgeschnitten - Ich bin überrascht, weil alte (bash3) Syntax, um eine Tonne auf die Eingabe speichern erlaubt ...

+3

Oh, warte. Sie erwarten, dass zwei verschiedene * Prozesssubstitutionen * generiert werden, nicht zwei Argumente für 'sed'? Ich weiß nicht, dass das ** jemals ** im Einklang mit korrektem, dokumentiertem Verhalten war ... das heißt, AFAIK, dein Code war abhängig von einem Fehler. –

+0

@CharlesDuffy - so hat es immer funktioniert (für mich und Skripte) bis bash4 upgrade - das '<(cmd {a, b})' hat sich in zwei '<(cmd a) <(cmd b)' erweitert und wurde übergeben in Join/etc. Diese Skripte nutzen diese Funktion ausgiebig, verschachteln sie auf mehreren Ebenen und Skripte werden getestet (ich wollte sie nicht mit meinen fetten Fingern berühren und neue Fehler erzeugen). – Vlad

+3

@Vlad Das scheint ein Fehler zu sein, den sie in Bash 4 behoben haben. Sie sollten erwarten, dass der Befehl innerhalb von <<(...) 'wie jeder andere Befehl geparst wird, also <(cmd {a, b})) 'sollte äquivalent zu' <(cmd ab) 'sein. – Barmar

Antwort

4

Das ursprüngliche Verhalten war undokumentiert (und im Gegensatz zu der allgemeinen Regel, dass Code, der in einer Prozesssubstitution eingeschlossen ist, wie eine Subshell oder ein ähnlicher Kontext, auf dieselbe Weise parst, in der er sich außerhalb derselben verhalten hätte).

Als solches war dies ein Fehler, kein Feature. Dieser Fehler wurde in bash-4.0-alpha behoben. Zitieren des CHANGES-Eintrags:

rr. Durch die Klammererweiterung können jetzt Prozesssubstitutionen unverändert durchlaufen werden.

Es sind keine Laufzeitflags verfügbar, um diese Änderung rückgängig zu machen.

+1

Ich habe in der Zwischenzeit in der gleichen Richtung gegraben, einen anderen betroffenen Benutzer gefunden (http://wiki.bash-hackers.org/syntax/expansion/brace), dann den gleichen Eintrag in CHANGES und alle git commits gefunden, die dazu geführt haben "commit bash-20080724 Schnappschuss". Zur Vereinfachung meines Ziels - ich werde die benutzerdefinierte bash4 für meine Box neu kompilieren und nur die Prioritätsänderung rückgängig machen, dann überprüfe ich die Skripte. Leider wurde es nicht den Laufzeitflags ausgesetzt, um mein Ziel zu vereinfachen. Lassen Sie mich alle Antworten auffrischen und Danke! – Vlad

Verwandte Themen