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

Исходное сообщение
"Видимость и время жизни переменных в sh/bash"

Отправлено anonymous , 27-Июл-11 21:41 
Есть код такого плана: команда формирует список, далее этот список передается по пайпу циклу while и инструкции read; к сожалению, после завершения цикла переменные перестают существовать. export var тоже не помогает. Пример кода:
ls / | while read dir1 dir2
do
...some commands...
export dir3=$dir1
done
echo $dir1
echo $dir3
Так вот, echo $dir1, $dir3 дает пустой результат.
Если сделать echo $dir1 в цикле - нормально, возвращает значение переменной. Как сохранить значение переменной после выхода из цикла?

Содержание

Сообщения в этом обсуждении
"Видимость и время жизни переменных в sh/bash"
Отправлено allez , 28-Июл-11 05:32 
> Так вот, echo $dir1, $dir3 дает пустой результат.
> Если сделать echo $dir1 в цикле - нормально, возвращает значение переменной. Как
> сохранить значение переменной после выхода из цикла?

Для этого необходимо отказаться от конвейера, передающего данные в цикл. Из-за этого цикл
выполняется в другом экземпляре оболочки и после его завершения она также завершается,
унося в небытие все переменные.

Попробуйте использовать, например, промежуточный файл и перенаправление:


ls / > file.lst
while read dir1 dir2
do
  ...some commands...
done < file.lst

P. S. Кстати, не вижу особого смысла считывать из потока ввода две переменных подряд.
Ведь ls будет выдавать по одному имени файла в строке и тогда переменная dir2 всегда будет
пустой. Это если в именах не будет пробелов. Если же пробелы будут, то в dir1 уйдет первое
слово имени, а в dir2 - все остальные. Есть риск получить кашу с винегретом. :-)


"Видимость и время жизни переменных в sh/bash"
Отправлено Аноним , 28-Июл-11 07:17 
>[оверквотинг удален]
> ls / | while read dir1 dir2
> do
> ...some commands...
> export dir3=$dir1
> done
> echo $dir1
> echo $dir3
> Так вот, echo $dir1, $dir3 дает пустой результат.
> Если сделать echo $dir1 в цикле - нормально, возвращает значение переменной. Как
> сохранить значение переменной после выхода из цикла?

dir3=`ls / | { while read dir1 dir2; do ...some commands...; done; echo $dir1; }`


"Видимость и время жизни переменных в sh/bash"
Отправлено allez , 28-Июл-11 10:25 
> dir3=`ls / | { while read dir1 dir2; do ...some commands...; done;
> echo $dir1; }`

Однако, индейская национальная народная изба получается. :-)


$ ls / | { while read dir1 dir2; do echo "'$dir1', '$dir2'"; done; echo "======"; echo "dir1 = '$dir1'"; }
'bin', ''
'boot', ''
'dev', ''
'etc', ''
'home', ''
'lib', ''
'lib64', ''
'lost+found', ''
'media', ''
'mnt', ''
'opt', ''
'proc', ''
'root', ''
'sbin', ''
'selinux', ''
'srv', ''
'sys', ''
'tmp', ''
'usr', ''
'var', ''
======
dir1 = ''


"Видимость и время жизни переменных в sh/bash"
Отправлено Аноним , 28-Июл-11 13:08 
>[оверквотинг удален]
> 'sbin', ''
> 'selinux', ''
> 'srv', ''
> 'sys', ''
> 'tmp', ''
> 'usr', ''
> 'var', ''
> ======
> dir1 = ''
>

:)
dir3=`ls / | { while read dir1 dir2; do echo $dir1 > /dev/null; dir=$dir1; done; echo $dir; }`
P.s. to subject sed, awk, http://ru.wikipedia.org/wiki/Программы_UNIX-подобных_операционных_систем


"Видимость и время жизни переменных в sh/bash"
Отправлено Аноним , 28-Июл-11 13:37 
#!/bin/bash
while read -r dir1; do  dir3=${dir3}\ ${dir1}; done < <(ls /); echo "$dir3";

"Видимость и время жизни переменных в sh/bash"
Отправлено Аноним , 28-Июл-11 14:06 
>[оверквотинг удален]
>> 'tmp', ''
>> 'usr', ''
>> 'var', ''
>> ======
>> dir1 = ''
>>
> :)
> dir3=`ls / | { while read dir1 dir2; do echo $dir1 >
> /dev/null; dir=$dir1; done; echo $dir; }`
> P.s. to subject sed, awk, http://ru.wikipedia.org/wiki/Программы_UNIX-подобных_операционных_систем

dir=`ls / | { while read dir1; do echo a > /dev/null; dir="${dir} ${dir1}"; done; echo $dir; }`;
read -r a b c << EOF
$dir
EOF
echo $a
bin
echo $b
boot
echo $c
dev ...


"Видимость и время жизни переменных в sh/bash"
Отправлено anonymous , 28-Июл-11 20:27 
>[оверквотинг удален]
> dir="${dir} ${dir1}"; done; echo $dir; }`;
> read -r a b c << EOF
> $dir
> EOF
> echo $a
> bin
> echo $b
> boot
> echo $c
> dev ...

Всем спасибо! Разобрался, как удачнее сделать в моем случае, но все предоставленные варианты были интересны и я их запомнил на будущее.;)