URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 8398
[ Назад ]

Исходное сообщение
"теряется значение переменной"

Отправлено любитель , 15-Авг-09 22:41 
Прошу помощи у знатоков шела.
При чтении со стандартного ввода все хорошо
скрипт

  #!/bin/bash
  a=0
  while read b; do
    [ $a -lt $b ] && a=$b
  done
  echo max: $a

запускаем
i@/home/i $ ./script
3
7
2
max: 7

Но при трении с конвеера:
file:
3
7
2

скрипт

  #!/bin/bash
  a=0
  cat file | while read b; do
    [ $a -lt $b ] && a=$b
    echo $a
  done
  echo max: $a

запускаем
i@/home/i $ ./script
3
7
7
max: 0

Почему потерялось значение переменной "a" при выходе из цикла? Это глюк, или особенность,
которую я не понимаю?


Содержание

Сообщения в этом обсуждении
"теряется значение переменной"
Отправлено gaa , 15-Авг-09 23:14 
>Почему потерялось значение переменной "a" при выходе из цикла? Это глюк, или
>особенность, которую я не понимаю?

Это особенность, которую ты не понимаешь. При подобном вызове (через
пайп) для while создаётся отдельный процесс и изменение переменных
происходит внутри него.

Для того, чтобы прокинуть значение переменной "наружу", сохрани её во
временный файл, а потом прочитай оттуда.


"теряется значение переменной"
Отправлено любитель , 15-Авг-09 23:23 
>>Почему потерялось значение переменной "a" при выходе из цикла? Это глюк, или
>>особенность, которую я не понимаю?
>
>Это особенность, которую ты не понимаешь. При подобном вызове (через
>пайп) для while создаётся отдельный процесс и изменение переменных
>происходит внутри него.
>
>Для того, чтобы прокинуть значение переменной "наружу", сохрани её во
>временный файл, а потом прочитай оттуда.

Спасибо, воспользуюсь подсказкой.


"теряется значение переменной"
Отправлено const86 , 16-Авг-09 03:57 
>Для того, чтобы прокинуть значение переменной "наружу", сохрани её во временный файл, а потом прочитай оттуда.

Бр-р-р... Можно вернуть через другой пайп: завернуть цикл в функцию, в которой сделать echo, и поймать снаружи через $(). Или поступить ещё хитрее: завернуть в функцию и заставить эту функцию сделать всю оставшуюся работу, но это может быть по-своему неудобно, смотря что за задача.


"теряется значение переменной"
Отправлено const86 , 16-Авг-09 03:59 
>  cat file | while read b; do

Чтобы избежать работы в subshell: while read b; do ...; done < file


"теряется значение переменной"
Отправлено любитель , 16-Авг-09 21:19 
Всем спасибо за помощь.
Остановился на варианте передачи значения через стандартный вывод,
который мне показался наиболее простым

getuid()
{
  ldapsearch -LLL -s one -b "ou=People,$SUFFIX" uidNumber | grep uidNumber | {
    maxuid=0
    while read s uid; do
      [ $uid -gt $maxuid ] && maxuid=$uid
    done
    echo $((maxuid + 1))
  }
}