Модераторы: powerfox, ZeeLax
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> туплю с командой read. видимость переменных 
:(
    Опции темы
leniviy
Дата 18.6.2008, 09:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: нет
Всего: 5



Здравствуйте. Есть программа, которая выводит результаты в виде таблицы. разделитель пробел. Хочу прочитать каждое поле в переменную. Обычная конструкция такая: 
Код

echo -e "1 2 3\n4 5 6" | while read A B C; do 
 echo "inside while read A=$A B=$B C=$C"; 
done
 
внутри цикла переменные видны. Но мне надо вызывать прогу (в данном случае echo "1 2 3") внутри другого цикла и сохранять прочитанные переменные до следующего вызова.
Код

A_SUM=0; B_SUM=0; C_SUM=0;
while [ 1 = 1 ]; do
 echo "1 2 3" | while read A B C; do 
  echo "inside while read A=$A B=$B C=$C"; 
 done
 A_SUM=$((A_SUM+A)); B_SUM=$((B_SUM+B)); C_SUM=$((C_SUM+C));
 echo "A_SUM=$A_SUM B_SUM=$B_SUM C_SUM=$C_SUM"; 
 sleep 1
done

вне цикла while read переменные $A, $B, $C не видны. Что же делать?

PM MAIL   Вверх
nickless
Дата 19.6.2008, 01:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


Профиль
Группа: Участник Клуба
Сообщений: 2976
Регистрация: 29.8.2005
Где: Germany

Репутация: 41
Всего: 181



while read... выполняется в subshell, соответственно все переменные изменяются только локально в цикле.

В bash есть переменная BASH_SUBSHELL, посмотри что выводит вот это:
Код

#!/bin/bash

echo "global"
echo "subshell level = $BASH_SUBSHELL"
while true; do
    echo "1 2 3" | while read A B C; do 
        echo "inside while read A=$A B=$B C=$C"; 
        echo "subshell level = $BASH_SUBSHELL"
    done
    echo "inside outer while"
    echo "subshell level = $BASH_SUBSHELL"
    sleep 1
done


Цитата(leniviy @  18.6.2008,  08:55 Найти цитируемый пост)
Что же делать?

Читать тут

Добавлено через 2 минуты и 20 секунд
ЗЫ. По шелл-программированию лучше спрашивать в общих вопросах.
Модератор: Тема перенесена


--------------------
user posted image

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
leniviy
Дата 19.6.2008, 10:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 552
Регистрация: 8.2.2003
Где: Спб

Репутация: нет
Всего: 5



Я понял как. Надо избавиться от пайпов примерно так:
Код

read A B C << HERE
 $(echo "1 2 3")
HERE
echo $A $B $C

правда я не понял, что такое "<<"
PM MAIL   Вверх
bilbobagginz
Дата 19.6.2008, 14:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Naughtius Maximus
****


Профиль
Группа: Экс. модератор
Сообщений: 8813
Регистрация: 2.3.2004
Где: Israel

Репутация: 113
Всего: 317



a я бы объяснил это явление проще: как в C или других языках, у переменных есть длинна жизни и scope.
если ты определяешь переменную ДО цикла, то ее значение сохранится.
а если определяешь во время цикла, то она умрёт после него.

можно сделать и так: создать спец. переменные до цикла, пользоваться своими ABC, и запихать их  в другие ( специальные)

если непонятно:
Код

#!/bin/sh

A_s=""
B_s=""
C_s=""

while [ 1 = 1 ]; do
 echo "1 2 3" | while read A B C; do 
  echo "inside while read A=$A B=$B C=$C"; 
  A_s="${A}"
  B_s="${B}"
  C_s="${C}"
 done
 A_SUM=$((A_SUM+A_s)); B_SUM=$((B_SUM+B_s)); C_SUM=$((C_SUM+C_s));
 echo "A_SUM=$A_SUM B_SUM=$B_SUM C_SUM=$C_SUM"; 
 sleep 1
done


но вообще-то так не рекомендуется работать.
принимают переменные по одной, проверку ввода делают.



--------------------
Я ещё не демон. Я только учусь.
PM WWW   Вверх
nickless
Дата 19.6.2008, 15:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


Профиль
Группа: Участник Клуба
Сообщений: 2976
Регистрация: 29.8.2005
Где: Germany

Репутация: 41
Всего: 181



Цитата(leniviy @  19.6.2008,  09:26 Найти цитируемый пост)
Надо избавиться от пайпов примерно так:

Можно конечно и heredoc-ом, но вообще по ссылке что я дал написано
Цитата

Piping  echo output to a read may produce unexpected results. In this scenario, the read  acts as if it were running in a subshell. Instead, use the set command



Цитата(bilbobagginz @  19.6.2008,  13:59 Найти цитируемый пост)
a я бы объяснил это явление проще: как в C или других языках, у переменных есть длинна жизни и scope.

В случае subshell ситуация сложнее, subshell выполняется как отдельный процесс (или симулирует это поведение), соответственно изменение любых переменных внутри subshell имеют только локальный эффект, даже export тут ничего не изменит.

Цитата(bilbobagginz @  19.6.2008,  13:59 Найти цитируемый пост)
можно сделать и так: создать спец. переменные до цикла, пользоваться своими ABC, и запихать их  в другие ( специальные)

Это сильно зависит от шелла, в bash (и если /bin/sh -> /bin/bash) работать не будет. В zsh работает. Какой у тебя шелл?

Добавлено через 5 минут и 37 секунд
Цитата(nickless @  19.6.2008,  14:57 Найти цитируемый пост)
вообще по ссылке что я дал написано

ЗЫ Конечно если используется bash, работает ли тот способ в других шеллах я не пробовал.


--------------------
user posted image

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Linux/UNIX: Oбщие вопросы"
nickless
Imple
nerezus

В тему здесь вопросы общие - не привязанные к определенному ПО или дистрибутиву BSD/Linux/UNIX.
Например вопросы о выборе ОС для определенных задач (но если Вы просто хотите узнать "Какой дистрибутив лучше", то для этого есть Клуб юнуксоидов).
Общие вопросы по shell-программированию тоже лучше задавать здесь.


  • Вопросы мобильной разработки тут
  • Вы должны соблюдать правила форума.
  • Помните: какой вопрос, такой и ответ. Прежде чем задать вопрос прочитайте вот эту статью на форуме CIT.
  • Оскорблять запрещается.
  • Религиозные войны в Религиозных войнах.
  • Общение "просто так" в Клубе юнуксоидов. В отличие от многих других разделов, здесь разрешается сдержанно оффтопить и юморить в тему.

За интересные статьи, находки, решения, программы и просто реальную помощь будут ставиться + в репу).


В данный момент этот раздел модерируют nerezus, nickless, powerfox, pythonwin, Imple и ZeeLax. Если вы хотите помочь нам, пишите в ПМ и мы обсудим.


Спасибо. И use UNIX or die; С уважением, nerezus, nickless, powerfox, pythonwin, Imple, ZeeLax.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | *NIX системы: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0478 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.