The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"Как передать знач. перем. из цикла в основн. скрипт"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"Как передать знач. перем. из цикла в основн. скрипт"  
Сообщение от a_pio email(ok) on 22-Май-06, 19:01 
Пример:
-------------------------------------
#!/bin/bash
M=0
for N in 1 2 3 4 5
do
let M=$M+$N
done
echo $M  # получается 0 !!!
-------------------------------------
Как я понимаю, для выполнения цикла bash запускает еще одну свою копию, копирует ей свое
окружение. А когда эта копия завешается, то переменная М не может быть передана обратно родителю и заменить собой его переменную М.
Эту проблему можно обойти записывая М каждый раз в файл, а потом, когда надо - прочитать.
Но, мне кажется, это дурной тон - писать в файл на каждой итерации цикла.
Пробовал export и declare - не помогает.

Как же все-таки передать значение переменной от ребенка к родителю?

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

 Оглавление

Сообщения по теме [Сортировка по времени, UBB]


1. "Как передать знач. перем. из цикла в основн. скрипт"  
Сообщение от allez (ok) on 22-Май-06, 20:04 
>Пример:
>-------------------------------------
>#!/bin/bash
>M=0
>for N in 1 2 3 4 5
>do
> let M=$M+$N
>done
>echo $M  # получается 0 !!!
>-------------------------------------
>Как я понимаю, для выполнения цикла bash запускает еще одну свою копию,
>копирует ей свое
>окружение. А когда эта копия завешается, то переменная М не может быть
>передана обратно родителю и заменить собой его переменную М.
>Эту проблему можно обойти записывая М каждый раз в файл, а потом,
>когда надо - прочитать.
>Но, мне кажется, это дурной тон - писать в файл на каждой
>итерации цикла.
>Пробовал export и declare - не помогает.
>
>Как же все-таки передать значение переменной от ребенка к родителю?

Что-то у вас не так... Вот что у меня bash выдает:

bash-2.05a$ cat test.sh
#!/usr/local/bin/bash
M=0
for N in 1 2 3 4 5
do
let M=$M+$N
done
echo $M

bash-2.05a$ ./test.sh
15

А у вас какие сообщения появляются на экране?

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

2. "Как передать знач. перем. из цикла в основн. скрипт"  
Сообщение от a_pio email(??) on 23-Май-06, 09:13 
>>Пример:
>>-------------------------------------
>>#!/bin/bash
>>M=0
>>for N in 1 2 3 4 5
>>do
>> let M=$M+$N
>>done
>>echo $M  # получается 0 !!!
>>-------------------------------------
>>Как я понимаю, для выполнения цикла bash запускает еще одну свою копию,
>>копирует ей свое
>>окружение. А когда эта копия завешается, то переменная М не может быть
>>передана обратно родителю и заменить собой его переменную М.
>>Эту проблему можно обойти записывая М каждый раз в файл, а потом,
>>когда надо - прочитать.
>>Но, мне кажется, это дурной тон - писать в файл на каждой
>>итерации цикла.
>>Пробовал export и declare - не помогает.
>>
>>Как же все-таки передать значение переменной от ребенка к родителю?
>
>Что-то у вас не так... Вот что у меня bash выдает:
>
>bash-2.05a$ cat test.sh
>#!/usr/local/bin/bash
>M=0
>for N in 1 2 3 4 5
>do
>let M=$M+$N
>done
>echo $M
>
>bash-2.05a$ ./test.sh
>15
>
>А у вас какие сообщения появляются на экране?

Да, вы правы. Я не прав. Приведенный мною пример неудачен. Я потом его сам набрал и
убедился, что он работает. Хотя и не понятно, почему.
Дело в том, что уже несколько лет я наступаю на эти грабли и всегда лень разобраться.
Как-нибудь обхожу эту проблему.
Попозже смогу привести реальный скрипт, где проявляется эта проблема.
Но мне кажется, что этот вопрос можно применить и к функциям.
Например. Объявляем функцию, а потом вызываем ее. Как можно получить результат ее работы?
Я знаю только три способа:
1. return 0 или 1 по условию, например.
2. PEREMENNAIA=`function abc 123`,
   тогда в функции нужно сделать, что-то типа "echo 456"
3. Внутри функции "echo $XXX >> file.ext".
   В основном скрипте "cat file.ext | while read ROW"
Третий способ самый удобный, когда в функции есть цикл с выводом данных, но и самый медленный и не красивый.
Идеальным вариантом было бы внутри функции устанавливать значения переменных, а в теле скрипта пользоваться ими.


Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

3. "Как передать знач. перем. из цикла в основн. скрипт"  
Сообщение от guest (??) on 23-Май-06, 12:09 
>Но мне кажется, что этот вопрос можно применить и к функциям.
>Например. Объявляем функцию, а потом вызываем ее. Как можно получить результат ее
>работы?
>Я знаю только три способа:
>1. return 0 или 1 по условию, например.
>2. PEREMENNAIA=`function abc 123`,
>   тогда в функции нужно сделать, что-то типа "echo 456"
>
>3. Внутри функции "echo $XXX >> file.ext".
>   В основном скрипте "cat file.ext | while read ROW"
>
>Третий способ самый удобный, когда в функции есть цикл с выводом данных,
>но и самый медленный и не красивый.
>Идеальным вариантом было бы внутри функции устанавливать значения переменных, а в теле
>скрипта пользоваться ими.

function result_in_var () {
    var=`long-command`
}

или

function result_in_stdout () {
   echo "hello"
   ...
}

result_in_stdout | while read ...

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

4. "Как передать знач. перем. из цикла в основн. скрипт"  
Сообщение от a_pio email(??) on 23-Май-06, 18:00 
>
>function result_in_var () {
>    var=`long-command`
>}
А в теле основного скрипта эта var будет пуста....

>result_in_stdout | while read ...
Вот за это спасибо. Недопер, что можно вывод функции перенаправить в конвеер.

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

5. "Как передать знач. перем. из цикла в основн. скрипт"  
Сообщение от a_pio email(??) on 23-Май-06, 18:20 
Вот кусок из конкретного скрипта подготовки данных для табеля рабочего времени.
Он построчно читает файл графика работы и преобразовывает его в три массива - начало,
конец и продолжительность рабочего дня.
Прошу не обращать внимание на бессмысленность последнего выода (3) - это только для примера.

#!/bin/bash
# Create grafic.csv. Only for example script!
cat << ! > grafic.csv.example
date,date,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31
user,ivanov,10:00-20:00,09:30-22:30,11:00-19:00,11:30-18:30,12:00-18:00,12:30-17:30,13:00-17:00,13:30-16:30,14:00-16:00,14:30-15:30,15:00-15:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00
user,petrov,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00
user,sidorov,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00,10:00-20:00
!

exec 2>$0.err
set -x

declare -a GRAFIC_TIMES
declare -a GRAFIC_TIMES_BEGIN
declare -a GRAFIC_TIMES_END
declare -a GRAFIC_TIMES_DELTA

############################################################################
function convert-time-human-unix() # 23:59 -> 12345
{
DATE=`echo $1 | tr ':,.' ':'`
MINUTES=`echo $DATE | cut -d : -f 2`
HOUERS=`echo $DATE | cut -d : -f 1`

#awk "BEGIN {print $SECONDS+$MINUTES*60+$HOUERS*3600}"
awk "BEGIN {print $MINUTES*60+$HOUERS*3600}"
}
############################################################################
function convert-time-unix-human() # 12345 -> 23:59
{
DATA=$1
let HOUERS=$DATA/3600
if [ $HOUERS -lt 10 ]
then
    HOUERS=0$HOUERS
fi

DATA=`awk "BEGIN {print $DATA-$HOUERS*3600}"`
let MINUTES=$DATA/60
if [ $MINUTES -lt 10 ]
then
    MINUTES=0$MINUTES
fi

echo "$HOUERS:$MINUTES"
}
###############################################################################
#
# BEGIN
#
GRAFIC_MONTH=05
GRAFIC_YEAR=2006

###############################################################################
#For every user
grep -e "^user," grafic.csv.example |
while read ROW
do

    OLD_IFS=$IFS
    IFS=","
    set $ROW
    IFS=$OLD_IFS
    USERNAME=$2
    shift 1
    GRAFIC_TIMES=($@)
### GRAFIC_TIMES=ivanov 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00 10:00-20:00

    let CNT=1
    while [ $CNT != ${#GRAFIC_TIMES[@]} ]
    do

    if [ $CNT -lt 10 ]
    then
        DAY=0$CNT
    else
        DAY=$CNT
    fi

    GRAFIC_TIME=${GRAFIC_TIMES[$CNT]}
        OLD_IFS=$IFS
    IFS="-"
        set $GRAFIC_TIME
    IFS=$OLD_IFS
    GRAFIC_TIME_BEGIN=$1
    GRAFIC_TIME_END=$2
    
    GRAFIC_TIME_BEGIN_SEC=`convert-time-human-unix $GRAFIC_TIME_BEGIN`
    GRAFIC_TIME_END_SEC=`convert-time-human-unix $GRAFIC_TIME_END`
    let GRAFIC_TIME_DELTA_SEC=$GRAFIC_TIME_END_SEC-$GRAFIC_TIME_BEGIN_SEC
    GRAFIC_TIME_DELTA=`convert-time-unix-human $GRAFIC_TIME_DELTA_SEC`

    GRAFIC_TIMES_BEGIN[$CNT]=$GRAFIC_TIME_BEGIN
    GRAFIC_TIMES_END[$CNT]=$GRAFIC_TIME_END
    GRAFIC_TIMES_DELTA[$CNT]=$GRAFIC_TIME_DELTA

    let CNT=$CNT+1

    echo ${GRAFIC_TIMES_BEGIN[@]} >  1.out # (1)
    echo ${GRAFIC_TIMES_END[@]}   >> 1.out
    echo ${GRAFIC_TIMES_DELTA[@]} >> 1.out
    done
    echo ${GRAFIC_TIMES_BEGIN[@]} >  2.out     # (2)
    echo ${GRAFIC_TIMES_END[@]}   >> 2.out
    echo ${GRAFIC_TIMES_DELTA[@]} >> 2.out
done
echo ${GRAFIC_TIMES_BEGIN[@]} >  3.out         # (3)
echo ${GRAFIC_TIMES_END[@]}   >> 3.out
echo ${GRAFIC_TIMES_DELTA[@]} >> 3.out

echo $SECONDS

Конец.
Так вот, вывод (1) содержит данные, (2) тоже, а вывод (3) пуст....

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

6. "Как передать знач. перем. из цикла в основн. скрипт"  
Сообщение от guest (??) on 23-Май-06, 19:28 
>>
>>function result_in_var () {
>>    var=`long-command`
>>}
>А в теле основного скрипта эта var будет пуста....

проверь. вот тебе рабочий пример:

function result_in_var () {
    var = $1
}

result_in_var 12345
echo $var

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

7. "Как передать знач. перем. из цикла в основн. скрипт"  
Сообщение от chip email(ok) on 24-Май-06, 01:28 

>function result_in_var () {
>    var = $1
^^^^

только пробелов перед и после присваивания не нужно:
var=$1

Правка | Высказать мнение | Ответить | Cообщить модератору | Наверх

Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ 1 | 2 | 3 | 4 | 5 ] [Рекомендовать для помещения в FAQ]




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2025 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру