2017-03-16 60 views
6

遺留系統之一升級到bash4,其大部分腳本停止工作。我已經縮小到如何在<(cmdA ...|cmdB ... file{1,2}|cmdZ ...)內展開大括號。爲什麼bash4以不同的方式擴展大括號?

爲了說明差異更好:

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

它是一個「硬編碼「(和預期?)更改爲bash4?或者是這種擴展的行爲受某些bash級設置(如set -B/set +B)控制,並且可以切換回舊/ legacy/bash3模式?我寧願改變一些shell的開關(而不是重寫一堆腳本)。

如果這(bash3)「功能」是一個bug修正或改進過程中切斷 - 我很驚訝,因爲舊的(bash3)語法允許以節省打字一噸......

+3

哦,等一下。你期望生成兩個不同的*進程替換*,而不是'sed'的兩個參數?我不知道那是**有史以來**符合正確的,記錄在案的行爲......也就是說,AFAIK,你的代碼取決於一個錯誤。 –

+0

@CharlesDuffy - 這就是它一直工作的原因(對於我和腳本),直到bash4升級 - <(cmd {a,b})'確實展開爲兩個<(cmd a)<(cmd b)'並且通過加入/等等。這些腳本廣泛使用此功能,將其嵌套到多個級別並對腳本進行測試(不想用胖手指觸摸它併產生新的錯誤)。 – Vlad

+3

@Vlad這看起來像一個bug,他們在Bash 4中修復了這個bug。你應該期望'<(...)'裏面的命令與任何其他命令一樣被解析,所以'<(cmd {a,b} )'應該等於'<(cmd ab)'。 – Barmar

回答

4

原來的行爲是沒有記錄(並且違背一般規則,即代碼包含在流程替換中,例如子外殼或類似的上下文,它們將以與它相同的方式進行解析)。

因此,這是一個錯誤,而不是一個功能。這個bug在bash-4.0-alpha中修復。引用CHANGES條目:

rr。 Brace擴展現在允許進程替換通過不變。

沒有用於恢復此更改的運行時標誌可用。

+1

我在同一時間挖掘,發現另一個受影響的用戶(http://wiki.bash-hackers.org/syntax/expansion/brace),然後在CHANGES中找到相同的條目,並找到了導致「提交bash-20080724快照」。爲了簡化我的目標 - 我將重新編譯自定義bash4作爲我的包裝盒,同時只恢復優先級更改,然後重新檢查腳本。悲傷的是它沒有暴露在運行時標誌來簡化我的目標。讓我贊成所有的答案,謝謝你! – Vlad

相關問題