LINUX.ORG.RU

Область видимости переменных в bash

 ,


0

1

Всем привет. Есть bash скрипт, в котором обрабатываю файлы в ffmpeg и надо в цикле запомнить название предыдущего файла. Пишу:

#!/bin/bash
PREV_PATH_FILE=""
...
while true
здесь выборка из базы
do
...
PREV_PATH_FILE="path_to_file"
#и если где-то здесь обратиться к переменной, то в ней будет значение
...
done
Но если обратиться к переменной при новой итерации цикла, то в ней будет пусто. Как можно запомнить это значение и записать в глобальную переменную, т.к. я так понял он создаёт локальную и пишет в неё, а при новой итерации использует глобальную?

что?

$ ./run.sh
#!/bin/bash

cat run.sh
echo "-------------"

tmp="123"
while true; do
  tmp="qwe"
  break
done

echo "tmp=$tmp"
-------------
tmp=qwe

anonymous ()

извините, плохо прочитал.

$ ./run.sh
#!/bin/bash

cat run.sh
echo "-------------"

fname=""
tmp=5
while echo "$tmp, $fname" && [ "$tmp" != "0" ] ; do
  tmp=$(($tmp-1))
  fname="qwe"
done

echo "tmp=$tmp"
-------------
5, 
4, qwe
3, qwe
2, qwe
1, qwe
0, qwe
tmp=0
что там не работает то?

anonymous ()
Ответ на: комментарий от anonymous

Переменная PREV_PATH_FILE видна из цикла, но если её значение поменять в цикле, то при следующей итерации она опять пустая, т.к. значение теряется. Как можно сделать так, чтоб она не затиралась?

trivium ()

Извиняюсь за оффтоп.
А зачем обрабатывать что-то на баш скриптах, когда есть питон например. имхо это проще. Почему баш лучше?

actics ()
Ответ на: комментарий от trivium

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

actics ()
Ответ на: комментарий от actics

хотя на других языках писать,имхо, удобнее

что тут можно сделать удобнее?
for i in *.avi;ffmpeg -i $i -vn -ar 44100 -ac 2 -ab 192 -f mp3 $i.mp3

zolden ★★★★★ ()
Ответ на: комментарий от actics

Bash позволяет узнавать разрешение и тип файлов через ffmpeg на лету без лишнего гемора. Но скрипт не я писал, я дописываю. И как всё таки поправить это?

trivium ()
Ответ на: комментарий от anonymous

в баше это видимо чревато, но это был не баш, я смухлевал и по синтаксису это видно

zolden ★★★★★ ()
Последнее исправление: zolden (всего исправлений: 1)
Ответ на: комментарий от trivium

в примере том переменная tmp (как и fname) видна из цикла и её значение меняется в цикле и при следующей итерации она измененная, что не понятно?

anonymous ()
Ответ на: комментарий от zolden

ну в таком случаи мб на баше проще. Но стоит добавить пару телодвижений и уже надо перл. а если ещё пару то как без питона я не знаю)

actics ()
$ ./run.sh 
#!/bin/bash

cat run.sh
echo "-------------"

PREV_PATH_FILE=""

# здесь выборка из базы
echo -e "123\nqwe\nasd" |
while read i; do
echo "before: $PREV_PATH_FILE"
PREV_PATH_FILE="$i"
#и если где-то здесь обратиться к переменной, то в ней будет значение
echo "after: $PREV_PATH_FILE"
done
-------------
before: 
after: 123
before: 123
after: qwe
before: qwe
after: asd
anonymous ()
Ответ на: комментарий от trivium

это не делает с переменной ничего особенного

anonymous ()
Ответ на: комментарий от trivium
#!/bin/bash

cat run.sh
echo "-------------"

PREV_PATH_FILE=""

# здесь выборка из базы
while true; do
echo "before: $PREV_PATH_FILE"
PREV_PATH_FILE="$RANDOM"
#и если где-то здесь обратиться к переменной, то в ней будет значение
echo "after: $PREV_PATH_FILE"
done
-------------
before: 
after: 29676
before: 29676
after: 18286
before: 18286
after: 3948
before: 3948
after: 15427
before: 15427
after: 27100
before: 27100
after: 8102
before: 8102
after: 20016
before: 20016
...
anonymous ()
Ответ на: комментарий от trivium

Переменная PREV_PATH_FILE видна из цикла, но если её значение поменять в цикле, то при следующей итерации она опять пустая, т.к. значение теряется. Как можно сделать так, чтоб она не затиралась?

Она не «затирается». while - это сабшел.

А вообще - man bash и учи уроки.

anonymous ()
Ответ на: комментарий от megabaks

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

actics ()
Ответ на: комментарий от actics

да дело вкуса больше, все равно что спрашивать, а когда нужно светлую тему в редакторе использовать.

anonymous ()

Выложи скрипт на пастебин.

Deleted ()
Ответ на: комментарий от anonymous

А если сделать так:

#!/bin/bash
while true
do
    echo "$PREV_FILE_PATH"

    mysql -h$DB_HOST -u $DB_USER -p$DB_PASS $DB_NAME ...;
    do

    PREV_FILE_PATH="777"
    done

done
То работает вот так:

127 127 127

Но если перенести PREV_FILE_PATH=«777» сразу перед последним done, то выводит так:

127
777
777
777
Читал про subshell и пробовал ставить в конце обоих done это: < <(find [путь к папке]) Но ничего это не изменило.

trivium ()
Ответ на: комментарий от trivium

Это из-за конвеера. Если написать так:

#!/bin/bash
while true
do
    echo "$PREV_FILE_PATH"

    PREV_FILE_PATH=`mysql -h$DB_HOST -u $DB_USER -p$DB_PASS $DB_NAME ... while read ...;
    do

    echo "777"
    done`

done
Но у меня в цикле идёт куча вывода текста. Можно как-то всё таки это починить?

trivium ()
Ответ на: комментарий от trivium

можно, если скрипт покажешь, а так получается: «а догадайтесь что у меня не правильно. давайте, давайте. где ваши варианты?» весь компрометирующий код можно стереть, но операторы баша оставить на месте и все что связано с той переменной не трогать

anonymous ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.