2014-08-29 3 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

Возможно, расскажите нам, что он должен делать, поскольку он не работает! –

+1

Интересно, если 'ssh' крадет ваши fds и читает/смывает их. Попробуйте закрыть stdin и '& 3' для команды' ssh'? –

+0

@EtanReisner Добавление '/dev/null' решило проблему. Спасибо =) –

ответ

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 

Или вы можете сделать это наоборот, если вы беспокоитесь о переменных внутри подоболочек:

#!/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

Под-оболочки, подразумеваемые с помощью труб, делают этот счетчик 'h' неправильным. –

+0

@EtanReisner Хорошо, спасибо. Я проверю утром - хотя я запустил его на своем Mac, и это показалось правильным. –

+0

@EtanReisner Кажется, что работает на моей машине. Существует только одна подоболочка, которая обрабатывает цикл while. Он наследует «h» от своего родителя при его запуске, а затем весело увеличивает его каждый раз через цикл. Я не вижу никакой проблемы - не могли бы вы объяснить, что вы имеете в виду, пожалуйста? –

Смежные вопросы