2014-08-29 50 views
1

如果我做了以下爲什麼在第一次迭代後停止?

tr -cd 'a-z' < /dev/urandom | fold -w10 | head -n40 > pw 
for f in $(seq -w 40); do echo linux$f.example.com;done > hosts 

while read -r x && read -r y <&3; do ssh $x -l root echo $y;done <hosts 3<pw 

則循環的第一次迭代後停止,但如果我插入一個echo(這是不是我想要的),那麼它遍歷所有40

while read -r x && read -r y <&3; do echo ssh $x -l root echo $y;done <hosts 3<pw 

問題

我怎樣才能讓它執行所有40次迭代,而無需先創建臨時文件?

+0

也許告訴我們它應該做什麼,因爲它不起作用! – 2014-08-29 22:17:58

+1

我不知道'ssh'是否在偷你的fds並閱讀/沖洗它們。嘗試關閉stdin和'&3'作爲'ssh'命令? – 2014-08-29 22:22:13

+0

@EtanReisner加入'/dev/null'解決了這個問題。謝謝=) – 2014-08-29 22:31:49

回答

1

這看起來像ssh正在看到和排空你的fds。

當您運行它時關閉fds到ssh

1

這樣如何避免臨時文件...

#!/bin/bash 
h=1 
LC_CTYPE="C" tr -cd 'a-z' < /dev/urandom | fold -w10 | head -n40 | \ 
    while read x; do 
     host=$(printf "linux%02d.example.com" $h) 
     echo $x $host 
     ((h++)) 
    done 

避免了臨時文件的另一種方法是使用過程中替換生成您所需要的兩個輸入端,然後將它們粘貼到兩兩讀數前單獨的行無論是在這樣一個循環:

#!/bin/bash 
paste \ 
    <(LC_CTYPE="C" tr -cd 'a-z' < /dev/urandom | fold -w10)  \ 
    <(for f in $(seq -w 40); do echo linux$f.example.com;done) | \ 
    head -n40 | while read x y; do 
     echo $x $y 
    done 

或者你也可以做周圍用另一種方式,如果你是擔心內部子shell變量:

#!/bin/bash 
while read x y; do 
    echo $x $y 
done < <(paste \ 
      <(LC_CTYPE="C" tr -cd 'a-z' < /dev/urandom | fold -w10)  \ 
      <(for f in $(seq -w 40); do echo linux$f.example.com;done) | \ 
      head -n40) 
+0

使用管道隱含的子shell使'h'計數器不能正常工作。 – 2014-08-29 23:01:21

+0

@EtanReisner好的,謝謝。我會在早上檢查 - 儘管我在我的Mac上運行過,看起來是正確的。 – 2014-08-29 23:08:29

+0

@EtanReisner它似乎在我的機器上運行良好。只涉及一個子shell,並處理'while'循環。它在父節點開始時從父節點繼承'h',然後每次通過循環快樂地遞增它。我看不出任何問題 - 你能解釋一下你的意思嗎? – 2014-08-30 07:15:46

相關問題