2009-10-07 4 views
1

Я не могу на всю жизнь видеть, почему я не могу прочитать postPrioity вне цикла while. Я пробовал «экспорт postPrioity =« 500 »« все еще не работал.Невозможно прочитать переменную, которая хранилась из цикла while, когда из цикла while

Любые идеи?

- или в плане текста -

#!/bin/bash 
cat "/files.txt" | while read namesInFile; do 
      postPrioity="500" 
      #This one shows the "$postPrioity" varible, as '500' 
      echo "weeeeeeeeee ---> $postPrioity <--- 1" 
done 
      #This one comes up with "" as the $postPrioity varible. GRRR 
      echo "weeeeeeeeee ---> $postPrioity <--- 2" 

ВЫВОД: (У меня только 3 имена файлов в files.txt)

weeeeeeeeee ---> 500 <--- 1 
weeeeeeeeee ---> 500 <--- 1 
weeeeeeeeee ---> 500 <--- 1 
weeeeeeeeee ---> <--- 2 

ответ

9

Оператор трубы создает подоболочку см BashPitfalls и BashFAQ. Решение: Не используйте cat, это бесполезно в любом случае.

#!/bin/bash 
postPriority=0 
while read namesInFile 
do 
    postPrioity=500 
    echo "weeeeeeeeee ---> $postPrioity <--- 1" 
done < /files.txt 
echo "weeeeeeeeee ---> $postPrioity <--- 2" 
+0

Спасибо за подтверждение моей догадки! Я думаю, что некоторые из других обходных решений, упомянутых в BashFAQ (например, группировка команд), - это лучшие ставки, хотя часто ваш конвейер не имеет смысла. – Cascabel

+1

Конечно, конвейеры не являются бессмысленными в каждом случае, но конструкция «cat file | ... "в большинстве случаев следует заменить на" ... <файл ". см., например, Bash Guide: http://mywiki.wooledge.org/BashGuide#BashGuide.2BAC8-Practices.2BAC8-DontEverDoThese.Don.27t_Ever_Do_These – Philipp

+0

Никогда не знал этого, я немного знал о подоболочке. Но да, не обращайте на это внимание сейчас, и вы будете читать на этих сайтах, спасибо. – Mint

6

В дополнение к реакции Филиппа в, в случае, если вы должны использовать трубку (и, как он отметил, в вашем примере вам не нужна кошка), вы можете поместить всю логику в одной и той же стороне труба:

 

command | { 
    while read line; do 
    variable=value 
    done 
    # Here $variable exists 
    echo $variable 
} 
# Here it doesn't 
 
1

В качестве альтернативы используют замену процесса:

while read line 
do  
    variable=value 
done < <(command)