LINUX.ORG.RU

Вash - область видимости

 


0

2

Вот пример скрипта:

$ cat -b ifcounter
     1	#!/bin/sh
     2	#ifcounter
     3	COUNTER=1OO
     4	echo "Do you wish to change the counter value currently set at "$COUNTER"? [y/n]"
     5	read ANS
     6	if [ $ANS = "y" ] || [ $ANS = "Y" ]; then
     7	  # да, пользователь желает изменить значение
     8	  echo "Enter a sensible value "
     9	  read VALUE
    10	  #простой тест, является ли значение численным (добавим к VALUE любое число),
    11	  #переменной STATUS присвоим значение кода возврата
    12	  expr $VALUE + 10 > /dev/null 2>&1
    13	  STATUS=$?
    14	  #проверим код возврата для ехрг
    15	    if [ $STATUS -ne 0 -o -z $VALUE ]; then
    16	      echo " You either entered nothing or a non-numeric " >&2
    17	      echo " Sorry now exiting..counter stays at $COUNTER " >&2
    18	    else
    19	      COUNTER=100
    20	      echo "\$COUNTER =" $COUNTER
    21	      echo "\$VALUE =" $VALUE
    22	      COUNTER=`expr $VALUE + $COUNTER`
    23	      echo "Counter now set to $COUNTER"
    24	      echo "Counter stays at $COUNTER"
    25	    fi
    26	fi

Вопрос следующий: если во вложении if стр.15 не указать значение переменной $COUNTER стр.19 то expr стр.22 не будет выполнен, поскольку во вложении не видна переменная $COUNTER назначенная выше, в теле сценария стр.3, по моему ИМХО мнению,скромного и не злобного ламера,переменная назначенная в стр.3 носит глобальный характер для всего сценария , то есть для дочерних процессов(оболочек) в том числе, однако это не так, в чем прикол кто-бы объяснил?



Последнее исправление: paco (всего исправлений: 3)

Посылаю тебе лучи ненависти за код на баше сполшным текстом и не обёрнутый в блок [сode]
cast cetjs2, Klymedy
// По сабжу сказать нечего

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

Модераторы кажется могут.

корректорам нельзя корректировать посты

Видимо для предотвращения корректорского произвола.

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

я все могу

форматирование поправил

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

Это будет слишком

Это будет через чур, подобное должно выполняться в среде сценария и его дочерних процессов,оно и выполняется если прописать стр.19, однако думаю все делается не так и проблема возможно кроется в районе вложений «if» ,применении «expr», попробуйте закоментируйте стр.19 и получите «expr: нецелочисленный аргумент», не видно переменной $COUNTER из вложения после «else»

paco
() автор топика

Хотел пройти мимо с следом своей ладони на лице, но если хочешь жить в лучшем мире, то кто же если не ты сам. Альтруизма пост.

5: read ANS

Если необходимо читать один символ, то легче всего себя обезопасить сказав read'у об этом: read -n 1 ANS.

6: if [ $ANS = «y» ] || [ $ANS = «Y» ]; then

Тут конечно ничего смертельного, но другие люди привыкли к использованию структуры вида: if [[ $ANS == "y" || $ANS == "Y" ]]; then. Первое, это использование более общей конструкции; второе, использовать «==» в место «=»: хоть в баше эти выражения равносильны, но не много людей об этом знают, и есть общие нормы таких выражений.

Плюс к этому, лучше экранировать переменные, которые проверяете. Ибо если в этом условии ANS будет, скажем, «123 456» (с пробелом), то скрипт упадёт с ошибкой. Итого финально должно быть if [[ "$ANS" == "y" || "$ANS" == "Y" ]]; then.

expr $VALUE + 10 > /dev/null 2>&1

Решение хоть и рабочее, но гораздо наглядней и прямее будет проверка через регулярное выражение (regexp).

20: echo «\$COUNTER =» $COUNTER
23: echo «Counter now set to $COUNTER»

Пишите в одном стиле: echo "\$COUNTER = $COUNTER".

// секция спорных советов, но об этом хотя бы стоит знать

В место $переменная - ${переменная}. Помимо больших возможностей этой конструкции, еще и повышается читабельность. Не злоупотреблять переменными в прописном буквенном регистре; у таких переменных, обычно, другое назначение.

iu0v1
()
Ответ на: ошибка от paco

Ошибка в том, что != — это сравнение строк, а не чисел.
man test, одним словом.

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

обезопасить

Чего.

но другие люди привыкли к использованию структуры вида

[[ $ANS == [yY] ]]

лучше экранировать переменные

Нет:

Word splitting and pathname expansion are not performed on the words between the [[ and ]]

Лучше сначала читать маны, а потом — давать советы, в общем.

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

!= — это сравнение строк, а не чисел.

согласен:

-nе if [ «$a» -ne «$b» ] Два числа не равны

-eq if [ «$a» -eq «$b» ] Два числа равны

,да не корректно спасибо, но вопрос не в этом, а в том почему переменной $COUNTER если закоментировать стр.19 не присваивается значение ответ будет таким:

$ ifcounter

Do you wish to change the counter value currently set at 1OO? [y/n]

y

Enter a sensible value

45

$COUNTER = 1OO

$VALUE = 45

expr: нецелочисленный аргумент

Counter now set to Counter stays at

$

если раскоментировать, то так:

$ ifcounter

Do you wish to change the counter value currently set at 1OO? [y/n]

y

Enter a sensible value 23

$COUNTER = 100

$VALUE = 23

Counter now set to 123

Counter stays at 123

$

paco
() автор топика

В теме у вас bash. В тегах bash. А в коде sh. :)

expr стр.22 не будет выполнен, поскольку во вложении не видна переменная $COUNTER назначенная выше

Она видна.

В COUNTER на строке 3 у вас цифра и две буквы «о», о чём сообщает ошибка «expr: нецелочисленный аргумент»:

COUNTER=`expr $VALUE + $COUNTER` # ошибку генерирует этот код

COUNTER на строке 19 - содержит нормальное число поэтому всё срабатывает.

P.S. Можно совет? Вам следует: 1. изменить способ поиска ошибок; 2. найти шрифт, в котором О != 0, 1 != l и т.д.; 3. заставить свой редактор числа и строки подсвечивать разными цветами.

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

на строке 3 у вас цифра и две буквы «о»

Спасибо, да конечно в этом и проблема, и за советы спасибо всем !!!...ТЕМА ЗАКРЫТА

paco
() автор топика
Ответ на: комментарий от salsa

DIGIT ZERO != LETTER O

Уважаемый! разрешите вопрос Как до вас это так быстро дошло ?, думаю не по ошибке «expr:не целочисленный аргумент» она могла возникнуть и по другим причинам, если вам будет не сложно ответить, буду весьма признателен!

paco
() автор топика
Ответ на: DIGIT ZERO != LETTER O от paco

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

salsa
()
Ответ на: DIGIT ZERO != LETTER O от paco

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

Второе - доверять ошибкам.
А вы пошли обратным путём решив, что интерпретатор ошибся.
Даже ошибку про зону видимости придумали. Да-да, именно придумали. :) И начали искать решение там, где светло, а не там, где потерялось.

Третье - смотреть, что написано.
Программа написала «expr: нецелочисленный аргумент», а вы не прочитали. :)
То есть глазами-то пробежали и на форуме запостили, но сути не поняли. Ведь если бы вы действительно прочли ошибку, то задались бы вопросом откель - откель ошибка? Ведь у expr на строке 12 «глушилка». Тогда что и где ругается?

Как-то так. :)

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

Как раз по ней(логично же, не?

СПАСИБО!!!

paco
() автор топика
Ответ на: комментарий от lexazloy

Даже ошибку про зону видимости придумали

.... не не придумал :), предположил СПАСИБО lexazloy, всем СПАСИБО, а предложенный к рассмотрению скрипт предпологаемый фрагмент более обширного сценария, скопировал я его без проверок с PDF-а, такая вот фигня, понравился комент «В теме у вас bash. В тегах bash. А в коде sh. :)» :)....by!

paco
() автор топика

Следует объявлять переменные с указанием типа (в данном случае - integer).

3 typeset -i COUNTER=100

Единичка и две буквы «О» сразу бы вызвали ошибку, на чём интрига бы и закончилась.

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